Libraries

library(plotly)
Warning: package ‘plotly’ was built under R version 4.1.3Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout

Data

hb_agesex <- read.csv("raw_data/covid_raw_data/hospital_admissions_hb_agesex_20220302.csv") %>% clean_names()
hb_names <- read_csv("raw_data/covid_raw_data/health_board_names.csv") %>% clean_names()

Data exploration

HB Age/sex dataset

Variables in dataset

hb_agesex %>% names()

hb_agesex %>% head()

hb_agesex %>% distinct(hb)

The health board number is not very useful or easy to make connections with, we should change this to the name of the health board

#select only the columns with health board names
hb_names <- hb_names %>% 
  select(hb, hb_name)
#join to get health board names
hb_agesex <- hb_agesex %>% 
  left_join(hb_names, by = "hb")
#Fill in NAs in hb_name - these are NA because the code is the country code for NHS Scotland
hb_agesex <- hb_agesex %>% 
  mutate(hb_name = if_else(
    is.na(hb_name),
    "All Scotland",
    hb_name
  )) 
hb_agesex %>% 
  distinct(admission_type)

We have three different admission types (all, emergency, planned) - should we only be looking at emergency admission types (e.g. acute)?

hb_agesex %>% 
  distinct(hb)
hb_agesex %>% 
  distinct(week_ending)
#change week_ending into date format
hb_agesex <- hb_agesex %>% 
  mutate(week_ending = ymd(week_ending))
hb_agesex <- hb_agesex %>% 
  mutate(month = month(week_ending, label = TRUE),
         year = year(week_ending), .after = week_ending)
#create winter and non winter groups
hb_agesex <- hb_agesex %>% 
  mutate(is_winter = if_else(
    month %in% c("Dec", "Jan", "Feb"), TRUE, FALSE
  ), .after = month)

Exploratory analysis

Compare mean admissions between Covid times and pre-Covid times

#compare mean admissions in 2020/2021/2022 with 2018/2019 averages
hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All") %>% 
  group_by(hb_name, week_ending) %>% 
  summarise(mean_admissions = mean(number_admissions),
            mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
    geom_line(aes(x = week_ending,
                  y = mean_admissions), group = 1, colour = "red") +
  geom_line(aes(x = week_ending,
                y = mean_20182019_admissions), group = 1, colour = "blue") +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4)+
  facet_wrap(~hb_name, scales = "free_y") + 
  labs(x = "Date",
       y = "Average admissions per week",
       colour = "Covid vs Pre-Covid")

Compare number of admissions between winter and non winter

No significant differences

#get boxplots to compare spread of number of admissions for winter vs not winter
hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All",
         hb_name == "All Scotland") %>% 
  ggplot(aes(x = number_admissions,
             y = is_winter)) +
  geom_boxplot() +
  geom_jitter(colour = "grey30", alpha = 0.5) 
  

Not expecting significant difference

H0 - number of admissions(winter) = number of admissions(not winter) H1 - number of admissions(winter) > number of admissions(not winter)

null_distribution <- hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All",
         hb_name == "All Scotland") %>% 
  specify(number_admissions ~ is_winter) %>% 
  hypothesise(null = "independence") %>% 
  generate(reps = 5000, type = "permute") %>% 
  calculate(stat = "diff in means", order = c("TRUE", "FALSE"))
observed_stat <- hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All",
         hb_name == "All Scotland") %>% 
  specify(number_admissions ~ is_winter) %>% 
  calculate(stat = "diff in means", order = c("TRUE", "FALSE"))
null_distribution %>% 
  visualise() +
  shade_p_value(obs_stat = observed_stat, direction = "right")
p_value <- null_distribution %>% 
  get_p_value(obs_stat = observed_stat, direction = "right")

p_value

Compare mean number of admissions for winter/not winter for different HBs

No significant differences

hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All",
         hb_name != "All Scotland") %>% 
  group_by(hb_name, is_winter) %>% 
  summarise(mean_num_admissions = mean(number_admissions)) %>% 
  ggplot(aes(x = hb_name,
             y = mean_num_admissions,
             fill = is_winter)) +
  geom_col(position = "dodge") +
  scale_y_sqrt()
`summarise()` has grouped output by 'hb_name'. You can override using the `.groups` argument.

NA
#compare percent variation for winter not winter
hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group == "All ages",
         sex == "All",
         hb_name == "All Scotland") %>% 
  ggplot(aes(x = percent_variation,
             y = is_winter)) +
  geom_boxplot() +
  geom_jitter(colour = "grey30", alpha = 0.5) 

Compare number of admissions by sex and winter/not winter

No significant differences

#get box plot for number of admissions by sex and whether or not it is winter
hb_agesex %>% 
  filter(sex != "All",
         admission_type == "Emergency",
         hb_name == "All Scotland") %>% 
  ggplot(aes(x = number_admissions,
             y = sex,
             colour = is_winter)) +
  geom_boxplot() +
  geom_jitter(colour = "grey30", alpha = 0.5)
  
#get bar graphs for mean number of admissions for each month by sex
hb_agesex %>% 
  filter(admission_type == "Emergency",
         sex != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, month, sex) %>% 
  summarise(mean_admissions = mean(number_admissions)) %>% 
  ggplot() +
    geom_col(aes(x = month,
                  y = mean_admissions, 
                  fill = sex), position = "dodge") 
`summarise()` has grouped output by 'hb_name', 'month'. You can override using the `.groups` argument.

hb_agesex %>% 
  filter(admission_type == "Emergency",
         sex != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, month, sex) %>% 
  summarise(mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
  geom_col(aes(x = month,
                  y = mean_20182019_admissions, 
                  fill = sex), position = "dodge")
`summarise()` has grouped output by 'hb_name', 'month'. You can override using the `.groups` argument.

Compare number of admissions for each age group for winter/not winter

For age groups over 65, admissions are slightly higher in the winter. The same pattern is not seen for younger age groups The increase in admissions in winter months for age groups over 65 was more drastic pre-Covid than during Covid. This is potentially due to the lockdown measures in winter Dec2020/Jan-Feb2021 and some remaining restrictions in winter Dec2021/Jan-Feb 2022 as well as the vaccination campaign targeting these age groups in early 2021 with boosters in late 2021/early 2022.

#get line graph of average number of admissions over time for each age group

hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, week_ending, age_group) %>% 
  summarise(mean_admissions = mean(number_admissions)) %>% 
  ggplot() +
    geom_line(aes(x = week_ending,
                  y = mean_admissions, 
                  colour = ordered(age_group, levels = c("Under 5",
                                                       "5 - 14",
                                                       "15 - 44",
                                                       "45 - 64",
                                                       "65 - 74",
                                                       "75 - 84",
                                                       "85 and over")))) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4)+
  labs(x = "Month",
       y = "Average number of admissions per week",
       colour = "Age group")
#get line graph comparing pre-Covid admissions to Covid admissions for each age group
hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, month, age_group) %>% 
  summarise(mean_admissions = mean(number_admissions),
            mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
    geom_line(aes(x = month,
                  y = mean_admissions), group = 1, colour = "red") +
    geom_line(aes(x = month,
                  y = mean_20182019_admissions), group = 1, colour = "blue") +
    facet_wrap(~age_group)
hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, age_group, is_winter) %>% 
  summarise(mean_admissions = mean(number_admissions)) %>% 
  ggplot() +
    geom_col(aes(x = ordered(age_group, levels = c("Under 5",
                                                       "5 - 14",
                                                       "15 - 44",
                                                       "45 - 64",
                                                       "65 - 74",
                                                       "75 - 84",
                                                       "85 and over")),
                  y = mean_admissions, 
                  fill = is_winter), position = "dodge") 



hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, age_group, is_winter) %>% 
  summarise(mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
  geom_col(aes(x = ordered(age_group, levels = c("Under 5",
                                                       "5 - 14",
                                                       "15 - 44",
                                                       "45 - 64",
                                                       "65 - 74",
                                                       "75 - 84",
                                                       "85 and over")),
                  y = mean_20182019_admissions, 
                  fill = is_winter), position = "dodge")

Graphs for dashboard

#get bar graph for mean number of admissions for each month by sex
covid_sex_plotly <- hb_agesex %>% 
  filter(admission_type == "Emergency",
         sex != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, month, sex) %>% 
  summarise(mean_admissions = mean(number_admissions),
            mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
    geom_col(aes(x = month,
                  y = mean_admissions, 
                  fill = sex,
                 text = paste0("Month: ", month,
                              "<br>",
                   "Average number of admissions: ", 
                   round(mean_admissions),
                 "<br>",
                 "2018/2019 avg admissions: ", 
                 round(mean_20182019_admissions))), 
             position = "dodge") +
  labs(title = "Average admissions by month 2020 - 2022",
       x = "\n Month",
       y = "Mean number of admissions",
       fill = "Sex")
`summarise()` has grouped output by 'hb_name', 'month'. You can override using the `.groups` argument.Warning: Ignoring unknown aesthetics: text
covid_sex_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) 
covid_age_plotly <- hb_agesex %>% 
  filter(admission_type == "Emergency",
         age_group != "All ages", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, age_group, is_winter) %>% 
  summarise(mean_admissions = mean(number_admissions),
            mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
  geom_col(aes(x = ordered(age_group, levels = c("Under 5",
                                                 "5 - 14",
                                                 "15 - 44",
                                                 "45 - 64",
                                                 "65 - 74",
                                                 "75 - 84",
                                                 "85 and over")),
               y = mean_admissions, 
               fill = if_else(is_winter == TRUE,
                              "Winter", "Not winter"),
               text = paste0("Age group: ", age_group,
                             "<br>",
                             "Average number of admissions: ", 
                             round(mean_admissions),
                             "<br>",
                             "2018/2019 avg admissions: ", 
                             round(mean_20182019_admissions))), 
           position = "dodge") +
  labs(title = "Average admissions by age group 2020 - 2022",
       x = "\n Age group",
       y = "Mean number of admissions",
       fill = "Season")
`summarise()` has grouped output by 'hb_name', 'age_group'. You can override using the `.groups` argument.Warning: Ignoring unknown aesthetics: text
covid_age_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) 

HB SIMD dataset

Variables in dataset

hb_simd <- read_csv("raw_data/covid_raw_data/hospital_admissions_hb_simd_20220302.csv") %>% clean_names()
hb_simd %>% names(
)

HB Specialty dataset

Variables in dataset

hb_specialty <- read_csv("raw_data/covid_raw_data/hospital_admissions_hb_specialty_20220302.csv") %>% clean_names()
hb_specialty %>% names()
#join with hb_names to get hb names
hb_specialty <- hb_specialty %>% 
  left_join(hb_names, by = "hb")
#change week_ending into date format
hb_specialty <- hb_specialty %>% 
  mutate(week_ending = ymd(week_ending))
hb_specialty <- hb_specialty %>% 
  mutate(month = month(week_ending, label = TRUE),
         year = year(week_ending), .after = week_ending)
#create winter and non winter groups
hb_specialty <- hb_specialty %>% 
  mutate(is_winter = if_else(
    month %in% c("Dec", "Jan", "Feb"), TRUE, FALSE
  ), .after = month)
#impute NAs in hb_name with all scotland b/c these are only for the all scotland hb code
hb_specialty <- hb_specialty %>% 
  mutate(hb_name = if_else(
    is.na(hb_name),
    "All Scotland",
    hb_name
  )) 

Exploratory analysis

#get graph for winter vs non-winter means by specialty for emergency admissions 

hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, specialty, is_winter) %>% 
  summarise(mean_admissions = mean(number_admissions)) %>% 
  ggplot() +
    geom_col(aes(x = specialty,
                  y = mean_admissions, 
                  fill = is_winter), position = "dodge") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) 



hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, specialty, is_winter) %>%  
  summarise(mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
    geom_col(aes(x = specialty,
                  y = mean_20182019_admissions, 
                  fill = is_winter), position = "dodge") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) 
#get winter vs non-winter means by specialty for emergency admissions 

hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, specialty, is_winter) %>% 
  summarise(median_admissions = median(number_admissions)) %>% 
  ggplot() +
    geom_col(aes(x = specialty,
                  y = median_admissions, 
                  fill = is_winter), position = "dodge") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) 



hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, specialty, is_winter) %>%  
  summarise(mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
    geom_col(aes(x = specialty,
                  y = mean_20182019_admissions, 
                  fill = is_winter), position = "dodge") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) 
#grouped summary table by admission type
hb_specialty %>% 
  filter(specialty == "All",
         hb_name == "All Scotland") %>% 
  group_by(admission_type) %>% 
  summarise(mean_admissions_covid = mean(number_admissions),
            mean_admissions_precovid = mean(average20182019),
            diff_mean_precovid_postcovid = mean_admissions_precovid - mean_admissions_covid)
#grouped summary table by specialty and admission type for all Scotland
hb_specialty %>% 
  filter(specialty != "All",
         hb_name == "All Scotland",
         admission_type != "All") %>% 
  group_by(month, specialty, admission_type) %>% 
  summarise(mean_admissions_covid = mean(number_admissions),
            mean_admissions_precovid = mean(average20182019),
            diff_mean_precovid_postcovid = mean_admissions_precovid - mean_admissions_covid) %>% 
  ggplot() +
  geom_point(aes(x = month,
            y = mean_admissions_covid),
            colour = "red") +
  geom_line(aes(x = month,
            y = mean_admissions_covid),
            colour = "red", group = 1) +
  geom_point(aes(x = month,
            y = mean_admissions_precovid),
            colour = "blue") +
  geom_line(aes(x = month,
            y = mean_admissions_precovid),
            colour = "blue", group = 1) +
  facet_grid(rows = vars(specialty),
             cols = vars(admission_type), scales = "free_y")
#grouped summary table of mean admissions by hb, specialty and admission type for each month
hb_specialty %>% 
  filter(specialty != "All",
         hb_name != "All Scotland",
         admission_type != "All") %>% 
  group_by(hb_name, month, specialty, admission_type) %>% 
  summarise(mean_admissions_covid = mean(number_admissions),
            mean_admissions_precovid = mean(average20182019),
            #get diff in means precovid vs during covid
            diff_mean_precovid_postcovid = mean_admissions_precovid - mean_admissions_covid) %>% 
  #see only observations where the mean admissions increased during covid years
  filter(diff_mean_precovid_postcovid <= -1)
hb_specialty %>% 
  filter(specialty != "All",
         hb_name != "All Scotland") %>% 
  group_by(hb_name, specialty, is_winter, admission_type) %>% 
  summarise(mean_admissions_covid = mean(number_admissions),
            mean_admissions_precovid = mean(average20182019),
            #get diff in means precovid vs during covid
            diff_mean_precovid_postcovid = mean_admissions_precovid - mean_admissions_covid) %>% 
  #see only observations where the mean admissions increased during covid years
  filter(diff_mean_precovid_postcovid <= -1)

For the average 20182019 admissions, certain specialties saw an increase in average number of emergency admissions per week during the winter period. These were: -Medical (both including and exluding Cardiology and Cancer) -Pediatrics (both including and exluding Cardiology and Cancer)

These same increases actually lessened during the Covid years 2020/2021/2022 to the point where there was only a small increase during the winter months. During the Covid years, there was a slight increase in average number of emergency admissions per week for Cardiology and for Surgery, which is notable because average emergency surgery admissions actually decreased in the winter pre-Covid

#get line graph of average number of admissions over time for each specialty

hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, week_ending, specialty) %>% 
  summarise(mean_admissions = mean(number_admissions)) %>% 
  ggplot() +
    geom_line(aes(x = week_ending,
                  y = mean_admissions, 
                  colour = specialty)) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4)+
  labs(x = "Date",
       y = "Average number of admissions per week",
       colour = "Specialty")
hb_specialty %>% 
  filter(admission_type == "Emergency",
         specialty != "All", 
         hb_name == "All Scotland") %>% 
  group_by(hb_name, month, specialty) %>% 
  summarise(mean_20182019_admissions = mean(average20182019)) %>% 
  ggplot() +
  geom_point(aes(x = month,
                  y = mean_20182019_admissions, 
                  colour = specialty)) +
    geom_line(aes(x = month,
                  y = mean_20182019_admissions, 
                  colour = specialty), group = hb_specialty$specialty) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
  labs(x = "Date",
       y = "Average number of admissions per week",
       colour = "Specialty")

HSCP Age/sex dataset

Variables in dataset

hscp_agesex <- read_csv("raw_data/covid_raw_data/hospital_admissions_hscp_agesex_20220302.csv") %>% clean_names()
hscp_agesex %>% names()

Again, the HSCP code is not very helpful, it would be more useful to have the HSCP names and the HB they are tied to.

#read in hscp names dataset
hscp_names <- read_csv("raw_data/covid_raw_data/hscp_names.csv") %>% clean_names()

#select the variables we need to add to the main table
hscp_names <- hscp_names %>% 
  select(hscp, hscp_name, hb, hb_name)
#join with hscp_names to get hscp and hb names

hscp_agesex <- hscp_agesex %>% left_join(hscp_names, by = "hscp")

Check to see if hb and hscp datasets are interchangable

I noticed that HSCP and HB datasets contained the same variables and HSCP datasets contained the HB as well, so I thought that they might be interchangable since, in theory, when you group HSCP datasets by HB, the number of admissions should aggregate to the same numbers as the HB datasets since they are for the same time periods. This isn’t the case. The HSCP dataset recorded higher numbers of admissions when aggregated by HB and compared with the HB dataset.

#summarise no of admissions by sex/age_group for each HB
hscp_agesex %>% 
  group_by(hb, sex, age_group, admission_type) %>% 
  summarise(total_admissions_by_sex = sum(number_admissions))
#summarise no of admissions by sex/age_group for each HB
hb_agesex %>% 
  group_by(hb, sex, age_group, admission_type) %>% 
  summarise(total_admissions_by_sex = sum(number_admissions))
#check number of admissions in each dataset for a random HB for the same week_ending date
hscp_agesex %>%
  select(week_ending, hb, age_group, sex, admission_type, number_admissions) %>% 
  filter(hb == "S08000015",
         week_ending == "20200105") %>% 
  group_by(week_ending, hb, sex, age_group, admission_type) %>% 
  summarise(total_admissions = sum(number_admissions))

hb_agesex %>%
  select(week_ending, hb, age_group, sex, admission_type, number_admissions) %>%
  filter(hb == "S08000015",
         week_ending == "2020-01-05") %>% 
  group_by(week_ending, hb, sex, age_group, admission_type) %>% 
  summarise(total_admissions = sum(number_admissions))

We should ask which dataset should be considered “correct” - I would suggest selecting the HSCP datasets b/c the numbers are higher, which makes me think that some admissions weren’t recorded in the HB dataset.

Can we get the proportion for no of admissions to population in each HB or HSCP? This would allow us to carry out statistical tests to see if any HBs or HSCPs have a higher proportion of admissions compared with Scotland overall

A&E attendance

ae_wait_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% clean_names()

Variables in dataset

ae_wait_times %>% names()

ae_wait_times %>% distinct(hbt) # note: need to join hb names

ae_wait_times %>% filter(is.na(number_meeting_target_aggregate))
#select only variables needed for summary table
ae_attendance_summary <- ae_wait_times %>% 
  select(month, hbt, number_of_attendances_aggregate, 
         discharge_destination_admission_to_same,
         discharge_destination_other_specialty,
         discharge_destination_residence,
         discharge_destination_transfer,
         discharge_destination_unknown)
#create separate month and year columns
ae_attendance_summary <- ae_attendance_summary %>% 
  mutate(month_year = month, .before = month)

ae_attendance_summary <- ae_attendance_summary %>% 
  mutate(month = month(ym(month_year), label = TRUE),
         year = year(ym(month_year)), .after = month_year)
#join with hb_names

ae_attendance_summary <- ae_attendance_summary %>% 
  left_join(hb_names, by = c("hbt" = "hb"))
#make all scotland attendance table
all_scotland_attendance <- ae_attendance_summary %>% 
  group_by(year, month) %>% 
  filter(year >= 2017) %>% 
  summarise(num_attendances = sum(number_of_attendances_aggregate),
            admission_to_same = sum(discharge_destination_admission_to_same, na.rm = TRUE),
            other_specialty = sum(discharge_destination_other_specialty, na.rm = TRUE),
            residence = sum(discharge_destination_residence, na.rm = TRUE),
            transfer = sum(discharge_destination_transfer, na.rm = TRUE),
            unknown = sum(discharge_destination_unknown, na.rm = TRUE))

#get proportions for destinations
all_scotland_attendance <- all_scotland_attendance %>% 
  rowwise() %>% 
  mutate(
    total_avg_discharge = sum(c(admission_to_same, other_specialty,
                                residence, transfer, unknown)),
    prop_admission = admission_to_same/total_avg_discharge,
    prop_other_specialty = other_specialty/total_avg_discharge,
    prop_residence = residence/total_avg_discharge,
    prop_transfer = transfer/total_avg_discharge,
    prop_unknown = unknown/total_avg_discharge
  )
ae_attendance_summary <- ae_attendance_summary %>% 
  group_by(hb_name, year, month) %>% 
  summarise(num_attendances = sum(number_of_attendances_aggregate),
           admission_to_same = sum(discharge_destination_admission_to_same, na.rm = TRUE),
            other_specialty = sum(discharge_destination_other_specialty, na.rm = TRUE),
            residence = sum(discharge_destination_residence, na.rm = TRUE),
            transfer = sum(discharge_destination_transfer, na.rm = TRUE),
            unknown = sum(discharge_destination_unknown, na.rm = TRUE))

ae_attendance_summary <- ae_attendance_summary %>% 
  rowwise() %>% 
  mutate(
    total_avg_discharge = sum(c(admission_to_same, other_specialty,
                                residence, transfer, unknown)),
    prop_admission = admission_to_same/total_avg_discharge,
    prop_other_specialty = other_specialty/total_avg_discharge,
    prop_residence = residence/total_avg_discharge,
    prop_transfer = transfer/total_avg_discharge,
    prop_unknown = unknown/total_avg_discharge
  )
#add columns to all scotland
all_scotland_attendance <- all_scotland_attendance %>% 
  mutate(hb_name = "All Scotland")
#select relevant columns
ae_attendance_summary <- ae_attendance_summary %>% 
  filter(year >=2017) %>% 
  select(year, month, hb_name, num_attendances, prop_admission, 
         prop_other_specialty, prop_residence, prop_transfer, prop_unknown)

all_scotland_attendance <- all_scotland_attendance %>% 
  select(year, month, hb_name, num_attendances, prop_admission,
         prop_other_specialty, prop_residence, prop_transfer, prop_unknown)
#bind rows
ae_attendance_summary <- ae_attendance_summary %>% 
  bind_rows(all_scotland_attendance)
#separate dataset into preCovid and Covid year ranges

covid_ae_attendance <- ae_attendance_summary %>% 
  filter(year >= 2020)

precovid_ae_attendance <- ae_attendance_summary %>% 
  filter(year < 2020)
#get 2017-2019 avgs to add as comparator to covid dataset

precovid_ae_attendance <- precovid_ae_attendance %>% 
  group_by(hb_name, month) %>% 
  summarise(avg_attendances_20171819 = mean(num_attendances),
            avg_prop_admission_20171829 = mean(prop_admission),
            avg_prop_other_specialty_20171819 = mean(prop_other_specialty),
            avg_prop_residence_20171819 = mean(prop_residence),
            avg_prop_transfer_20171819 = mean(prop_transfer),
            avg_prop_unknown_20171819 = mean(prop_unknown)) 

#create key to join with covid_ae_attendance
precovid_ae_attendance <- precovid_ae_attendance %>% 
  mutate(hb_key = paste0(hb_name, "_", month), .before = hb_name)

#select only key and avg variables
precovid_ae_attendance <- precovid_ae_attendance %>% 
  subset(select = -c(hb_name, month))

  
covid_ae_attendance <- covid_ae_attendance %>% 
  mutate(hb_key = paste0(hb_name, "_", month), .before = hb_name)
covid_ae_attendance <- covid_ae_attendance %>% 
  left_join(precovid_ae_attendance, by = "hb_key")
covid_ae_attendance <- covid_ae_attendance %>% 
  mutate(date = (paste0(year, "-", month)), .before = year) %>% 
  mutate(date = ym(date), .before = year)
#put data in long format

covid_ae_attendance <- covid_ae_attendance %>% 
  pivot_longer(
    cols = starts_with("prop"),
    names_to = "destination",
    values_to = "destination_prop"
  )

covid_ae_attendance <- covid_ae_attendance %>% 
  mutate(
    avg_prop_20171819 = case_when(
      destination == "prop_admission" ~ avg_prop_admission_20171829,
      destination == "prop_other_specialty" ~ avg_prop_other_specialty_20171819,
      destination == "prop_residence" ~ avg_prop_residence_20171819,
      destination == "prop_transfer" ~ avg_prop_transfer_20171819,
      destination == "prop_unknown" ~ avg_prop_unknown_20171819
    )
  )

covid_ae_attendance <- covid_ae_attendance %>% 
  select(date, year, month, hb_key, hb_name, num_attendances, 
         avg_attendances_20171819, destination,
         destination_prop, avg_prop_20171819)

Graphs for dashboard

covid_ae_attendance_plotly <- covid_ae_attendance %>% 
  filter(hb_name == "All Scotland") %>% 
  ggplot() +
  geom_point(aes(x = date,
                 y = num_attendances,
                 text = paste0("Date: ", year, "-", month,
                              "<br>",
                   "Number of admissions: ", num_attendances,
                 "<br>",
                 "2017-2019 avg admissions: ", 
                 round(avg_attendances_20171819)))) +
  geom_line(aes(x = date,
                y = num_attendances)) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50")+
  labs(title = "Number of attendances at A&E 2020 - 2022 \n",
       x = "Date",
       y = "Number of Attendances")
Warning: Ignoring unknown aesthetics: text
covid_ae_attendance_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) %>% 
  layout(hoverlabel = list(bgcolor = "white"))
covid_ae_destinations_plotly <- covid_ae_attendance %>% 
  filter(hb_name == "All Scotland") %>% 
  ggplot() +
  geom_point(aes(x = date,
                 y = destination_prop,
                 colour = destination,
                 text = paste0("Date: ", year, "-", month,
                               "<br>",
                               "Percentage: ", 
                              round(destination_prop*100, digits = 2), 
                              "%",
                              "<br>",
                              "2017-2019 percentage: ", 
                              round(avg_prop_20171819*100, digits = 2), 
                              "%"))) +
  geom_line(aes(x = date,
                 y = destination_prop,
                group = destination)) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  scale_y_sqrt() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
   geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50")+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50")+
  labs(title = "Destination of attendances at A&E 2020 - 2022 \n",
       x = "Date",
       y = "Proportion of attendances",
       colour = "Destination")
Warning: Ignoring unknown aesthetics: text
covid_ae_destinations_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE)
NA
NA

Waiting times - Lloyd’s graph

Read data, manipulate table

waiting_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% clean_names()
Rows: 15837 Columns: 25-- Column specification -------------------------------------------------------------------------------------------
Delimiter: ","
chr (13): Country, HBT, TreatmentLocation, DepartmentType, NumberOfAttendancesEpisodeQF, NumberMeetingTargetEpi...
dbl (12): Month, NumberOfAttendancesAggregate, NumberOfAttendancesEpisode, NumberMeetingTargetAggregate, Number...
i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
#get date and quarter values 
waiting_times <- waiting_times %>% 
  mutate(date = ym(month),
         quarter = quarter(date))
#get proportions for all destinations
waiting_times <- waiting_times %>% 
  mutate(
    prop_admission_to_same = (discharge_destination_admission_to_same/number_of_attendances_aggregate)
  ) %>% 
  mutate(prop_other_speciality = (discharge_destination_other_specialty/number_of_attendances_aggregate)) %>% 
  mutate(prop_residence = (discharge_destination_residence/number_of_attendances_aggregate)) %>% 
  mutate(prop_transfer = (discharge_destination_transfer/number_of_attendances_aggregate)) %>% 
  mutate(prop_unknown = (discharge_destination_unknown/number_of_attendances_aggregate)) 
#change to long format
waiting_times <- waiting_times %>%
  pivot_longer(cols = prop_admission_to_same:prop_unknown, names_to = "discharge_destination", values_to = "discharge_proportion")

#clean up values for destinations
waiting_times <- waiting_times %>%
  mutate(discharge_destination = case_when(
    str_detect(discharge_destination, "prop_admission_to_same") ~ 
      "Admission to Same Facility",
    str_detect(discharge_destination, "prop_other_speciality") ~ 
      "Discharged to private provider/died",
    str_detect(discharge_destination, "prop_residence") ~ 
      "Discharged to private residence",
    str_detect(discharge_destination, "prop_transfer") ~ 
      "Transferred to another NHS provider",
    str_detect(discharge_destination, "prop_unknown") ~ 
      "Unknown or other discharge destination"
  ))

Graphs for dashboard

#read in clean data
waiting_times <- read_csv("clean_data/wait_times.csv")
Rows: 79185 Columns: 29-- Column specification ------------------------------------------------------------------------------------------
Delimiter: ","
chr  (14): country, hbt, treatment_location, department_type, number_of_attendances_episode_qf, number_meeting...
dbl  (14): month, number_of_attendances_aggregate, number_of_attendances_episode, number_meeting_target_aggreg...
date  (1): date
i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
winter_plotly <- waiting_times %>% 
  filter(discharge_destination == "Admission to Same Facility",
         !is.na(discharge_proportion)) %>% 
  group_by(date) %>% 
  summarise(mean_admission_to_same = mean(discharge_proportion)) %>% 
  ggplot() +
  geom_point(aes(x = date,
         y = mean_admission_to_same,
         text =  paste0("Date: ", date,
                               "<br>",
                               "Percentage: ", 
                              round(mean_admission_to_same*100, digits = 2), 
                              "%"))) +
  geom_line(aes(x = date,
         y = mean_admission_to_same)) +
  scale_x_date(date_breaks = "6 months", date_labels =  "%b %Y") +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7)) +
  geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2021-01-01")), linetype=4, colour = "grey50", alpha = 0.7)+
  geom_vline(xintercept = as.numeric(as.Date("2022-01-01")), linetype=4, colour = "grey50", alpha = 0.7) +
  labs(title = "Proportion of attendances to selected destination \n",
       x = "\n Date",
       y = "Proportion of attendances")
Warning: Ignoring unknown aesthetics: text
winter_plotly %>% 
  ggplotly(tooltip = "text") %>% 
  config(displayModeBar = FALSE) %>% 
layout(hoverlabel = list(bgcolor = "white"))
NA
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIExpYnJhcmllcw0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShpbmZlcikNCmxpYnJhcnkocGxvdGx5KQ0KYGBgDQoNCiMgRGF0YQ0KDQpgYGB7cn0NCmhiX2FnZXNleCA8LSByZWFkLmNzdigicmF3X2RhdGEvY292aWRfcmF3X2RhdGEvaG9zcGl0YWxfYWRtaXNzaW9uc19oYl9hZ2VzZXhfMjAyMjAzMDIuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCmhiX25hbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9jb3ZpZF9yYXdfZGF0YS9oZWFsdGhfYm9hcmRfbmFtZXMuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCmBgYA0KDQoNCiMgRGF0YSBleHBsb3JhdGlvbg0KDQojIyBIQiBBZ2Uvc2V4IGRhdGFzZXQNCg0KIyMjIFZhcmlhYmxlcyBpbiBkYXRhc2V0DQoNCmBgYHtyfQ0KaGJfYWdlc2V4ICU+JSBuYW1lcygpDQoNCmhiX2FnZXNleCAlPiUgaGVhZCgpDQoNCmhiX2FnZXNleCAlPiUgZGlzdGluY3QoaGIpDQpgYGANCg0KDQoNClRoZSBoZWFsdGggYm9hcmQgbnVtYmVyIGlzIG5vdCB2ZXJ5IHVzZWZ1bCBvciBlYXN5IHRvIG1ha2UgY29ubmVjdGlvbnMgd2l0aCwgd2Ugc2hvdWxkIGNoYW5nZSB0aGlzIHRvIHRoZSBuYW1lIG9mIHRoZSBoZWFsdGggYm9hcmQNCg0KYGBge3J9DQojc2VsZWN0IG9ubHkgdGhlIGNvbHVtbnMgd2l0aCBoZWFsdGggYm9hcmQgbmFtZXMNCmhiX25hbWVzIDwtIGhiX25hbWVzICU+JSANCiAgc2VsZWN0KGhiLCBoYl9uYW1lKQ0KYGBgDQoNCg0KYGBge3J9DQojam9pbiB0byBnZXQgaGVhbHRoIGJvYXJkIG5hbWVzDQpoYl9hZ2VzZXggPC0gaGJfYWdlc2V4ICU+JSANCiAgbGVmdF9qb2luKGhiX25hbWVzLCBieSA9ICJoYiIpDQpgYGANCg0KYGBge3J9DQojRmlsbCBpbiBOQXMgaW4gaGJfbmFtZSAtIHRoZXNlIGFyZSBOQSBiZWNhdXNlIHRoZSBjb2RlIGlzIHRoZSBjb3VudHJ5IGNvZGUgZm9yIE5IUyBTY290bGFuZA0KaGJfYWdlc2V4IDwtIGhiX2FnZXNleCAlPiUgDQogIG11dGF0ZShoYl9uYW1lID0gaWZfZWxzZSgNCiAgICBpcy5uYShoYl9uYW1lKSwNCiAgICAiQWxsIFNjb3RsYW5kIiwNCiAgICBoYl9uYW1lDQogICkpIA0KYGBgDQoNCmBgYHtyfQ0KaGJfYWdlc2V4ICU+JSANCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUpDQpgYGANCldlIGhhdmUgdGhyZWUgZGlmZmVyZW50IGFkbWlzc2lvbiB0eXBlcyAoYWxsLCBlbWVyZ2VuY3ksIHBsYW5uZWQpIC0gc2hvdWxkIHdlIG9ubHkgYmUgbG9va2luZyBhdCBlbWVyZ2VuY3kgYWRtaXNzaW9uIHR5cGVzIChlLmcuIGFjdXRlKT8NCg0KYGBge3J9DQpoYl9hZ2VzZXggJT4lIA0KICBkaXN0aW5jdChoYikNCmBgYA0KDQpgYGB7cn0NCmhiX2FnZXNleCAlPiUgDQogIGRpc3RpbmN0KHdlZWtfZW5kaW5nKQ0KYGBgDQoNCmBgYHtyfQ0KI2NoYW5nZSB3ZWVrX2VuZGluZyBpbnRvIGRhdGUgZm9ybWF0DQpoYl9hZ2VzZXggPC0gaGJfYWdlc2V4ICU+JSANCiAgbXV0YXRlKHdlZWtfZW5kaW5nID0geW1kKHdlZWtfZW5kaW5nKSkNCmBgYA0KDQpgYGB7cn0NCmhiX2FnZXNleCA8LSBoYl9hZ2VzZXggJT4lIA0KICBtdXRhdGUobW9udGggPSBtb250aCh3ZWVrX2VuZGluZywgbGFiZWwgPSBUUlVFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKHdlZWtfZW5kaW5nKSwgLmFmdGVyID0gd2Vla19lbmRpbmcpDQpgYGANCg0KDQpgYGB7cn0NCiNjcmVhdGUgd2ludGVyIGFuZCBub24gd2ludGVyIGdyb3Vwcw0KaGJfYWdlc2V4IDwtIGhiX2FnZXNleCAlPiUgDQogIG11dGF0ZShpc193aW50ZXIgPSBpZl9lbHNlKA0KICAgIG1vbnRoICVpbiUgYygiRGVjIiwgIkphbiIsICJGZWIiKSwgVFJVRSwgRkFMU0UNCiAgKSwgLmFmdGVyID0gbW9udGgpDQpgYGANCg0KDQojIyMgRXhwbG9yYXRvcnkgYW5hbHlzaXMNCg0KIyMjIyBDb21wYXJlIG1lYW4gYWRtaXNzaW9ucyBiZXR3ZWVuIENvdmlkIHRpbWVzIGFuZCBwcmUtQ292aWQgdGltZXMNCmBgYHtyfQ0KI2NvbXBhcmUgbWVhbiBhZG1pc3Npb25zIGluIDIwMjAvMjAyMS8yMDIyIHdpdGggMjAxOC8yMDE5IGF2ZXJhZ2VzDQpoYl9hZ2VzZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBhZ2VfZ3JvdXAgPT0gIkFsbCBhZ2VzIiwNCiAgICAgICAgIHNleCA9PSAiQWxsIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCB3ZWVrX2VuZGluZykgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucyksDQogICAgICAgICAgICBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fbGluZShhZXMoeCA9IHdlZWtfZW5kaW5nLA0KICAgICAgICAgICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9ucyksIGdyb3VwID0gMSwgY29sb3VyID0gInJlZCIpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gd2Vla19lbmRpbmcsDQogICAgICAgICAgICAgICAgeSA9IG1lYW5fMjAxODIwMTlfYWRtaXNzaW9ucyksIGdyb3VwID0gMSwgY29sb3VyID0gImJsdWUiKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIzIG1vbnRocyIsIGRhdGVfbGFiZWxzID0gIiViICVZIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSArDQogICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjAtMDEtMDEiKSksIGxpbmV0eXBlPTQpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjEtMDEtMDEiKSksIGxpbmV0eXBlPTQpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksIGxpbmV0eXBlPTQpKw0KICBmYWNldF93cmFwKH5oYl9uYW1lLCBzY2FsZXMgPSAiZnJlZV95IikgKyANCiAgbGFicyh4ID0gIkRhdGUiLA0KICAgICAgIHkgPSAiQXZlcmFnZSBhZG1pc3Npb25zIHBlciB3ZWVrIiwNCiAgICAgICBjb2xvdXIgPSAiQ292aWQgdnMgUHJlLUNvdmlkIikNCmBgYA0KDQojIyMjIENvbXBhcmUgbnVtYmVyIG9mIGFkbWlzc2lvbnMgYmV0d2VlbiB3aW50ZXIgYW5kIG5vbiB3aW50ZXINCg0KTm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMNCg0KYGBge3J9DQojZ2V0IGJveHBsb3RzIHRvIGNvbXBhcmUgc3ByZWFkIG9mIG51bWJlciBvZiBhZG1pc3Npb25zIGZvciB3aW50ZXIgdnMgbm90IHdpbnRlcg0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgYWdlX2dyb3VwID09ICJBbGwgYWdlcyIsDQogICAgICAgICBzZXggPT0gIkFsbCIsDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG51bWJlcl9hZG1pc3Npb25zLA0KICAgICAgICAgICAgIHkgPSBpc193aW50ZXIpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV9qaXR0ZXIoY29sb3VyID0gImdyZXkzMCIsIGFscGhhID0gMC41KSANCiAgDQpgYGANCg0KTm90IGV4cGVjdGluZyBzaWduaWZpY2FudCBkaWZmZXJlbmNlDQoNCkgwIC0gbnVtYmVyIG9mIGFkbWlzc2lvbnMod2ludGVyKSA9IG51bWJlciBvZiBhZG1pc3Npb25zKG5vdCB3aW50ZXIpDQpIMSAtIG51bWJlciBvZiBhZG1pc3Npb25zKHdpbnRlcikgPiBudW1iZXIgb2YgYWRtaXNzaW9ucyhub3Qgd2ludGVyKQ0KDQpgYGB7cn0NCm51bGxfZGlzdHJpYnV0aW9uIDwtIGhiX2FnZXNleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIGFnZV9ncm91cCA9PSAiQWxsIGFnZXMiLA0KICAgICAgICAgc2V4ID09ICJBbGwiLA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBzcGVjaWZ5KG51bWJlcl9hZG1pc3Npb25zIH4gaXNfd2ludGVyKSAlPiUgDQogIGh5cG90aGVzaXNlKG51bGwgPSAiaW5kZXBlbmRlbmNlIikgJT4lIA0KICBnZW5lcmF0ZShyZXBzID0gNTAwMCwgdHlwZSA9ICJwZXJtdXRlIikgJT4lIA0KICBjYWxjdWxhdGUoc3RhdCA9ICJkaWZmIGluIG1lYW5zIiwgb3JkZXIgPSBjKCJUUlVFIiwgIkZBTFNFIikpDQpgYGANCg0KYGBge3J9DQpvYnNlcnZlZF9zdGF0IDwtIGhiX2FnZXNleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIGFnZV9ncm91cCA9PSAiQWxsIGFnZXMiLA0KICAgICAgICAgc2V4ID09ICJBbGwiLA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBzcGVjaWZ5KG51bWJlcl9hZG1pc3Npb25zIH4gaXNfd2ludGVyKSAlPiUgDQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoIlRSVUUiLCAiRkFMU0UiKSkNCmBgYA0KDQpgYGB7cn0NCm51bGxfZGlzdHJpYnV0aW9uICU+JSANCiAgdmlzdWFsaXNlKCkgKw0KICBzaGFkZV9wX3ZhbHVlKG9ic19zdGF0ID0gb2JzZXJ2ZWRfc3RhdCwgZGlyZWN0aW9uID0gInJpZ2h0IikNCmBgYA0KYGBge3J9DQpwX3ZhbHVlIDwtIG51bGxfZGlzdHJpYnV0aW9uICU+JSANCiAgZ2V0X3BfdmFsdWUob2JzX3N0YXQgPSBvYnNlcnZlZF9zdGF0LCBkaXJlY3Rpb24gPSAicmlnaHQiKQ0KDQpwX3ZhbHVlDQpgYGANCiMjIyMgQ29tcGFyZSBtZWFuIG51bWJlciBvZiBhZG1pc3Npb25zIGZvciB3aW50ZXIvbm90IHdpbnRlciBmb3IgZGlmZmVyZW50IEhCcw0KDQpObyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcw0KDQpgYGB7cn0NCmhiX2FnZXNleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIGFnZV9ncm91cCA9PSAiQWxsIGFnZXMiLA0KICAgICAgICAgc2V4ID09ICJBbGwiLA0KICAgICAgICAgaGJfbmFtZSAhPSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBpc193aW50ZXIpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fbnVtX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBoYl9uYW1lLA0KICAgICAgICAgICAgIHkgPSBtZWFuX251bV9hZG1pc3Npb25zLA0KICAgICAgICAgICAgIGZpbGwgPSBpc193aW50ZXIpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV95X3NxcnQoKQ0KICANCmBgYA0KDQpgYGB7cn0NCiNjb21wYXJlIHBlcmNlbnQgdmFyaWF0aW9uIGZvciB3aW50ZXIgbm90IHdpbnRlcg0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgYWdlX2dyb3VwID09ICJBbGwgYWdlcyIsDQogICAgICAgICBzZXggPT0gIkFsbCIsDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHBlcmNlbnRfdmFyaWF0aW9uLA0KICAgICAgICAgICAgIHkgPSBpc193aW50ZXIpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV9qaXR0ZXIoY29sb3VyID0gImdyZXkzMCIsIGFscGhhID0gMC41KSANCmBgYA0KDQoNCg0KDQoNCg0KIyMjIyBDb21wYXJlIG51bWJlciBvZiBhZG1pc3Npb25zIGJ5IHNleCBhbmQgd2ludGVyL25vdCB3aW50ZXINCg0KTm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMNCg0KYGBge3J9DQojZ2V0IGJveCBwbG90IGZvciBudW1iZXIgb2YgYWRtaXNzaW9ucyBieSBzZXggYW5kIHdoZXRoZXIgb3Igbm90IGl0IGlzIHdpbnRlcg0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKHNleCAhPSAiQWxsIiwNCiAgICAgICAgIGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBudW1iZXJfYWRtaXNzaW9ucywNCiAgICAgICAgICAgICB5ID0gc2V4LA0KICAgICAgICAgICAgIGNvbG91ciA9IGlzX3dpbnRlcikpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBnZW9tX2ppdHRlcihjb2xvdXIgPSAiZ3JleTMwIiwgYWxwaGEgPSAwLjUpDQogIA0KYGBgDQoNCmBgYHtyfQ0KI2dldCBiYXIgZ3JhcGhzIGZvciBtZWFuIG51bWJlciBvZiBhZG1pc3Npb25zIGZvciBlYWNoIG1vbnRoIGJ5IHNleA0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgc2V4ICE9ICJBbGwiLCANCiAgICAgICAgIGhiX25hbWUgPT0gIkFsbCBTY290bGFuZCIpICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgbW9udGgsIHNleCkgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucykpICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fY29sKGFlcyh4ID0gbW9udGgsDQogICAgICAgICAgICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25zLCANCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBzZXgpLCBwb3NpdGlvbiA9ICJkb2RnZSIpIA0KDQoNCg0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgc2V4ICE9ICJBbGwiLCANCiAgICAgICAgIGhiX25hbWUgPT0gIkFsbCBTY290bGFuZCIpICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgbW9udGgsIHNleCkgJT4lIA0KICBzdW1tYXJpc2UobWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zID0gbWVhbihhdmVyYWdlMjAxODIwMTkpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9jb2woYWVzKHggPSBtb250aCwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgZmlsbCA9IHNleCksIHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KIyMjIyBDb21wYXJlIG51bWJlciBvZiBhZG1pc3Npb25zIGZvciBlYWNoIGFnZSBncm91cCBmb3Igd2ludGVyL25vdCB3aW50ZXINCkZvciBhZ2UgZ3JvdXBzIG92ZXIgNjUsIGFkbWlzc2lvbnMgYXJlIHNsaWdodGx5IGhpZ2hlciBpbiB0aGUgd2ludGVyLiBUaGUgc2FtZSBwYXR0ZXJuIGlzIG5vdCBzZWVuIGZvciB5b3VuZ2VyIGFnZSBncm91cHMNClRoZSBpbmNyZWFzZSBpbiBhZG1pc3Npb25zIGluIHdpbnRlciBtb250aHMgZm9yIGFnZSBncm91cHMgb3ZlciA2NSB3YXMgbW9yZSBkcmFzdGljIHByZS1Db3ZpZCB0aGFuIGR1cmluZyBDb3ZpZC4gVGhpcyBpcyBwb3RlbnRpYWxseSBkdWUgdG8gdGhlIGxvY2tkb3duIG1lYXN1cmVzIGluIHdpbnRlciBEZWMyMDIwL0phbi1GZWIyMDIxIGFuZCBzb21lIHJlbWFpbmluZyByZXN0cmljdGlvbnMgaW4gd2ludGVyIERlYzIwMjEvSmFuLUZlYiAyMDIyIGFzIHdlbGwgYXMgdGhlIHZhY2NpbmF0aW9uIGNhbXBhaWduIHRhcmdldGluZyB0aGVzZSBhZ2UgZ3JvdXBzIGluIGVhcmx5IDIwMjEgd2l0aCBib29zdGVycyBpbiBsYXRlIDIwMjEvZWFybHkgMjAyMi4NCg0KDQpgYGB7cn0NCiNnZXQgbGluZSBncmFwaCBvZiBhdmVyYWdlIG51bWJlciBvZiBhZG1pc3Npb25zIG92ZXIgdGltZSBmb3IgZWFjaCBhZ2UgZ3JvdXANCg0KaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgYWdlX2dyb3VwICE9ICJBbGwgYWdlcyIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCB3ZWVrX2VuZGluZywgYWdlX2dyb3VwKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9saW5lKGFlcyh4ID0gd2Vla19lbmRpbmcsDQogICAgICAgICAgICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25zLCANCiAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG9yZGVyZWQoYWdlX2dyb3VwLCBsZXZlbHMgPSBjKCJVbmRlciA1IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDE0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUgLSA0NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjQ1IC0gNjQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI2NSAtIDc0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNzUgLSA4NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjg1IGFuZCBvdmVyIikpKSkgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMyBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgKw0KICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgbGFicyh4ID0gIk1vbnRoIiwNCiAgICAgICB5ID0gIkF2ZXJhZ2UgbnVtYmVyIG9mIGFkbWlzc2lvbnMgcGVyIHdlZWsiLA0KICAgICAgIGNvbG91ciA9ICJBZ2UgZ3JvdXAiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCiNnZXQgbGluZSBncmFwaCBjb21wYXJpbmcgcHJlLUNvdmlkIGFkbWlzc2lvbnMgdG8gQ292aWQgYWRtaXNzaW9ucyBmb3IgZWFjaCBhZ2UgZ3JvdXANCmhiX2FnZXNleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIGFnZV9ncm91cCAhPSAiQWxsIGFnZXMiLCANCiAgICAgICAgIGhiX25hbWUgPT0gIkFsbCBTY290bGFuZCIpICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgbW9udGgsIGFnZV9ncm91cCkgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucyksDQogICAgICAgICAgICBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fbGluZShhZXMoeCA9IG1vbnRoLA0KICAgICAgICAgICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9ucyksIGdyb3VwID0gMSwgY29sb3VyID0gInJlZCIpICsNCiAgICBnZW9tX2xpbmUoYWVzKHggPSBtb250aCwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMpLCBncm91cCA9IDEsIGNvbG91ciA9ICJibHVlIikgKw0KICAgIGZhY2V0X3dyYXAofmFnZV9ncm91cCkNCmBgYA0KYGBge3J9DQpoYl9hZ2VzZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBhZ2VfZ3JvdXAgIT0gIkFsbCBhZ2VzIiwgDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIGFnZV9ncm91cCwgaXNfd2ludGVyKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9jb2woYWVzKHggPSBvcmRlcmVkKGFnZV9ncm91cCwgbGV2ZWxzID0gYygiVW5kZXIgNSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUgLSAxNCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjE1IC0gNDQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0NSAtIDY0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNjUgLSA3NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjc1IC0gODQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI4NSBhbmQgb3ZlciIpKSwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuX2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgZmlsbCA9IGlzX3dpbnRlciksIHBvc2l0aW9uID0gImRvZGdlIikgDQoNCg0KDQpoYl9hZ2VzZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBhZ2VfZ3JvdXAgIT0gIkFsbCBhZ2VzIiwgDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIGFnZV9ncm91cCwgaXNfd2ludGVyKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX2NvbChhZXMoeCA9IG9yZGVyZWQoYWdlX2dyb3VwLCBsZXZlbHMgPSBjKCJVbmRlciA1IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDE0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUgLSA0NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjQ1IC0gNjQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI2NSAtIDc0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNzUgLSA4NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjg1IGFuZCBvdmVyIikpLA0KICAgICAgICAgICAgICAgICAgeSA9IG1lYW5fMjAxODIwMTlfYWRtaXNzaW9ucywgDQogICAgICAgICAgICAgICAgICBmaWxsID0gaXNfd2ludGVyKSwgcG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCiMjIyBHcmFwaHMgZm9yIGRhc2hib2FyZA0KDQpgYGB7cn0NCiNnZXQgYmFyIGdyYXBoIGZvciBtZWFuIG51bWJlciBvZiBhZG1pc3Npb25zIGZvciBlYWNoIG1vbnRoIGJ5IHNleA0KY292aWRfc2V4X3Bsb3RseSA8LSBoYl9hZ2VzZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBzZXggIT0gIkFsbCIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBtb250aCwgc2V4KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSwNCiAgICAgICAgICAgIG1lYW5fMjAxODIwMTlfYWRtaXNzaW9ucyA9IG1lYW4oYXZlcmFnZTIwMTgyMDE5KSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9jb2woYWVzKHggPSBtb250aCwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuX2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgZmlsbCA9IHNleCwNCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiTW9udGg6ICIsIG1vbnRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICJBdmVyYWdlIG51bWJlciBvZiBhZG1pc3Npb25zOiAiLCANCiAgICAgICAgICAgICAgICAgICByb3VuZChtZWFuX2FkbWlzc2lvbnMpLA0KICAgICAgICAgICAgICAgICAiPGJyPiIsDQogICAgICAgICAgICAgICAgICIyMDE4LzIwMTkgYXZnIGFkbWlzc2lvbnM6ICIsIA0KICAgICAgICAgICAgICAgICByb3VuZChtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMpKSksIA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgYWRtaXNzaW9ucyBieSBtb250aCAyMDIwIC0gMjAyMiIsDQogICAgICAgeCA9ICJcbiBNb250aCIsDQogICAgICAgeSA9ICJNZWFuIG51bWJlciBvZiBhZG1pc3Npb25zIiwNCiAgICAgICBmaWxsID0gIlNleCIpDQoNCmNvdmlkX3NleF9wbG90bHkgJT4lIA0KICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUgDQogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKSANCmBgYA0KDQpgYGB7cn0NCmNvdmlkX2FnZV9wbG90bHkgPC0gaGJfYWdlc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiLA0KICAgICAgICAgYWdlX2dyb3VwICE9ICJBbGwgYWdlcyIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBhZ2VfZ3JvdXAsIGlzX3dpbnRlcikgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucyksDQogICAgICAgICAgICBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX2NvbChhZXMoeCA9IG9yZGVyZWQoYWdlX2dyb3VwLCBsZXZlbHMgPSBjKCJVbmRlciA1IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDE0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUgLSA0NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjQ1IC0gNjQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI2NSAtIDc0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNzUgLSA4NCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjg1IGFuZCBvdmVyIikpLA0KICAgICAgICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9ucywgDQogICAgICAgICAgICAgICBmaWxsID0gaWZfZWxzZShpc193aW50ZXIgPT0gVFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaW50ZXIiLCAiTm90IHdpbnRlciIpLA0KICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiQWdlIGdyb3VwOiAiLCBhZ2VfZ3JvdXAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF2ZXJhZ2UgbnVtYmVyIG9mIGFkbWlzc2lvbnM6ICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChtZWFuX2FkbWlzc2lvbnMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDE4LzIwMTkgYXZnIGFkbWlzc2lvbnM6ICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMpKSksIA0KICAgICAgICAgICBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIGFkbWlzc2lvbnMgYnkgYWdlIGdyb3VwIDIwMjAgLSAyMDIyIiwNCiAgICAgICB4ID0gIlxuIEFnZSBncm91cCIsDQogICAgICAgeSA9ICJNZWFuIG51bWJlciBvZiBhZG1pc3Npb25zIiwNCiAgICAgICBmaWxsID0gIlNlYXNvbiIpDQoNCmNvdmlkX2FnZV9wbG90bHkgJT4lIA0KICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUgDQogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKSANCmBgYA0KDQoNCiMjIEhCIFNJTUQgZGF0YXNldA0KDQojIyMgVmFyaWFibGVzIGluIGRhdGFzZXQNCg0KYGBge3J9DQpoYl9zaW1kIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9jb3ZpZF9yYXdfZGF0YS9ob3NwaXRhbF9hZG1pc3Npb25zX2hiX3NpbWRfMjAyMjAzMDIuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCmBgYA0KDQpgYGB7cn0NCmhiX3NpbWQgJT4lIG5hbWVzKA0KKQ0KYGBgDQoNCiMjIEhCIFNwZWNpYWx0eSBkYXRhc2V0DQoNCiMjIyBWYXJpYWJsZXMgaW4gZGF0YXNldA0KDQpgYGB7cn0NCmhiX3NwZWNpYWx0eSA8LSByZWFkX2NzdigicmF3X2RhdGEvY292aWRfcmF3X2RhdGEvaG9zcGl0YWxfYWRtaXNzaW9uc19oYl9zcGVjaWFsdHlfMjAyMjAzMDIuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCmBgYA0KYGBge3J9DQpoYl9zcGVjaWFsdHkgJT4lIG5hbWVzKCkNCmBgYA0KDQoNCg0KYGBge3J9DQojam9pbiB3aXRoIGhiX25hbWVzIHRvIGdldCBoYiBuYW1lcw0KaGJfc3BlY2lhbHR5IDwtIGhiX3NwZWNpYWx0eSAlPiUgDQogIGxlZnRfam9pbihoYl9uYW1lcywgYnkgPSAiaGIiKQ0KYGBgDQoNCg0KYGBge3J9DQojY2hhbmdlIHdlZWtfZW5kaW5nIGludG8gZGF0ZSBmb3JtYXQNCmhiX3NwZWNpYWx0eSA8LSBoYl9zcGVjaWFsdHkgJT4lIA0KICBtdXRhdGUod2Vla19lbmRpbmcgPSB5bWQod2Vla19lbmRpbmcpKQ0KYGBgDQoNCmBgYHtyfQ0KaGJfc3BlY2lhbHR5IDwtIGhiX3NwZWNpYWx0eSAlPiUgDQogIG11dGF0ZShtb250aCA9IG1vbnRoKHdlZWtfZW5kaW5nLCBsYWJlbCA9IFRSVUUpLA0KICAgICAgICAgeWVhciA9IHllYXIod2Vla19lbmRpbmcpLCAuYWZ0ZXIgPSB3ZWVrX2VuZGluZykNCmBgYA0KDQoNCmBgYHtyfQ0KI2NyZWF0ZSB3aW50ZXIgYW5kIG5vbiB3aW50ZXIgZ3JvdXBzDQpoYl9zcGVjaWFsdHkgPC0gaGJfc3BlY2lhbHR5ICU+JSANCiAgbXV0YXRlKGlzX3dpbnRlciA9IGlmX2Vsc2UoDQogICAgbW9udGggJWluJSBjKCJEZWMiLCAiSmFuIiwgIkZlYiIpLCBUUlVFLCBGQUxTRQ0KICApLCAuYWZ0ZXIgPSBtb250aCkNCmBgYA0KDQpgYGB7cn0NCiNpbXB1dGUgTkFzIGluIGhiX25hbWUgd2l0aCBhbGwgc2NvdGxhbmQgYi9jIHRoZXNlIGFyZSBvbmx5IGZvciB0aGUgYWxsIHNjb3RsYW5kIGhiIGNvZGUNCmhiX3NwZWNpYWx0eSA8LSBoYl9zcGVjaWFsdHkgJT4lIA0KICBtdXRhdGUoaGJfbmFtZSA9IGlmX2Vsc2UoDQogICAgaXMubmEoaGJfbmFtZSksDQogICAgIkFsbCBTY290bGFuZCIsDQogICAgaGJfbmFtZQ0KICApKSANCmBgYA0KDQoNCiMjIyBFeHBsb3JhdG9yeSBhbmFseXNpcw0KDQpgYGB7cn0NCiNnZXQgZ3JhcGggZm9yIHdpbnRlciB2cyBub24td2ludGVyIG1lYW5zIGJ5IHNwZWNpYWx0eSBmb3IgZW1lcmdlbmN5IGFkbWlzc2lvbnMgDQoNCmhiX3NwZWNpYWx0eSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIHNwZWNpYWx0eSAhPSAiQWxsIiwgDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIHNwZWNpYWx0eSwgaXNfd2ludGVyKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnMgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9jb2woYWVzKHggPSBzcGVjaWFsdHksDQogICAgICAgICAgICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25zLCANCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBpc193aW50ZXIpLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSANCg0KDQoNCmhiX3NwZWNpYWx0eSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIHNwZWNpYWx0eSAhPSAiQWxsIiwgDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIHNwZWNpYWx0eSwgaXNfd2ludGVyKSAlPiUgIA0KICBzdW1tYXJpc2UobWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zID0gbWVhbihhdmVyYWdlMjAxODIwMTkpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX2NvbChhZXMoeCA9IHNwZWNpYWx0eSwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgZmlsbCA9IGlzX3dpbnRlciksIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9NykpIA0KDQpgYGANCmBgYHtyfQ0KI2dldCB3aW50ZXIgdnMgbm9uLXdpbnRlciBtZWFucyBieSBzcGVjaWFsdHkgZm9yIGVtZXJnZW5jeSBhZG1pc3Npb25zIA0KDQpoYl9zcGVjaWFsdHkgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBzcGVjaWFsdHkgIT0gIkFsbCIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBzcGVjaWFsdHksIGlzX3dpbnRlcikgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuX2FkbWlzc2lvbnMgPSBtZWRpYW4obnVtYmVyX2FkbWlzc2lvbnMpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX2NvbChhZXMoeCA9IHNwZWNpYWx0eSwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWRpYW5fYWRtaXNzaW9ucywgDQogICAgICAgICAgICAgICAgICBmaWxsID0gaXNfd2ludGVyKSwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgDQoNCg0KDQpoYl9zcGVjaWFsdHkgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBzcGVjaWFsdHkgIT0gIkFsbCIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBzcGVjaWFsdHksIGlzX3dpbnRlcikgJT4lICANCiAgc3VtbWFyaXNlKG1lYW5fMjAxODIwMTlfYWRtaXNzaW9ucyA9IG1lYW4oYXZlcmFnZTIwMTgyMDE5KSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9jb2woYWVzKHggPSBzcGVjaWFsdHksDQogICAgICAgICAgICAgICAgICB5ID0gbWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zLCANCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBpc193aW50ZXIpLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSANCg0KYGBgDQoNCg0KDQoNCg0KYGBge3J9DQojZ3JvdXBlZCBzdW1tYXJ5IHRhYmxlIGJ5IGFkbWlzc2lvbiB0eXBlDQpoYl9zcGVjaWFsdHkgJT4lIA0KICBmaWx0ZXIoc3BlY2lhbHR5ID09ICJBbGwiLA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zX2NvdmlkID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucyksDQogICAgICAgICAgICBtZWFuX2FkbWlzc2lvbnNfcHJlY292aWQgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSksDQogICAgICAgICAgICBkaWZmX21lYW5fcHJlY292aWRfcG9zdGNvdmlkID0gbWVhbl9hZG1pc3Npb25zX3ByZWNvdmlkIC0gbWVhbl9hZG1pc3Npb25zX2NvdmlkKQ0KYGBgDQoNCmBgYHtyfQ0KI2dyb3VwZWQgc3VtbWFyeSB0YWJsZSBieSBzcGVjaWFsdHkgYW5kIGFkbWlzc2lvbiB0eXBlIGZvciBhbGwgU2NvdGxhbmQNCmhiX3NwZWNpYWx0eSAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHkgIT0gIkFsbCIsDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiLA0KICAgICAgICAgYWRtaXNzaW9uX3R5cGUgIT0gIkFsbCIpICU+JSANCiAgZ3JvdXBfYnkobW9udGgsIHNwZWNpYWx0eSwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fYWRtaXNzaW9uc19jb3ZpZCA9IG1lYW4obnVtYmVyX2FkbWlzc2lvbnMpLA0KICAgICAgICAgICAgbWVhbl9hZG1pc3Npb25zX3ByZWNvdmlkID0gbWVhbihhdmVyYWdlMjAxODIwMTkpLA0KICAgICAgICAgICAgZGlmZl9tZWFuX3ByZWNvdmlkX3Bvc3Rjb3ZpZCA9IG1lYW5fYWRtaXNzaW9uc19wcmVjb3ZpZCAtIG1lYW5fYWRtaXNzaW9uc19jb3ZpZCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBtb250aCwNCiAgICAgICAgICAgIHkgPSBtZWFuX2FkbWlzc2lvbnNfY292aWQpLA0KICAgICAgICAgICAgY29sb3VyID0gInJlZCIpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gbW9udGgsDQogICAgICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25zX2NvdmlkKSwNCiAgICAgICAgICAgIGNvbG91ciA9ICJyZWQiLCBncm91cCA9IDEpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IG1vbnRoLA0KICAgICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9uc19wcmVjb3ZpZCksDQogICAgICAgICAgICBjb2xvdXIgPSAiYmx1ZSIpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gbW9udGgsDQogICAgICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25zX3ByZWNvdmlkKSwNCiAgICAgICAgICAgIGNvbG91ciA9ICJibHVlIiwgZ3JvdXAgPSAxKSArDQogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoc3BlY2lhbHR5KSwNCiAgICAgICAgICAgICBjb2xzID0gdmFycyhhZG1pc3Npb25fdHlwZSksIHNjYWxlcyA9ICJmcmVlX3kiKQ0KYGBgDQoNCg0KYGBge3J9DQojZ3JvdXBlZCBzdW1tYXJ5IHRhYmxlIG9mIG1lYW4gYWRtaXNzaW9ucyBieSBoYiwgc3BlY2lhbHR5IGFuZCBhZG1pc3Npb24gdHlwZSBmb3IgZWFjaCBtb250aA0KaGJfc3BlY2lhbHR5ICU+JSANCiAgZmlsdGVyKHNwZWNpYWx0eSAhPSAiQWxsIiwNCiAgICAgICAgIGhiX25hbWUgIT0gIkFsbCBTY290bGFuZCIsDQogICAgICAgICBhZG1pc3Npb25fdHlwZSAhPSAiQWxsIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBtb250aCwgc3BlY2lhbHR5LCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hZG1pc3Npb25zX2NvdmlkID0gbWVhbihudW1iZXJfYWRtaXNzaW9ucyksDQogICAgICAgICAgICBtZWFuX2FkbWlzc2lvbnNfcHJlY292aWQgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSksDQogICAgICAgICAgICAjZ2V0IGRpZmYgaW4gbWVhbnMgcHJlY292aWQgdnMgZHVyaW5nIGNvdmlkDQogICAgICAgICAgICBkaWZmX21lYW5fcHJlY292aWRfcG9zdGNvdmlkID0gbWVhbl9hZG1pc3Npb25zX3ByZWNvdmlkIC0gbWVhbl9hZG1pc3Npb25zX2NvdmlkKSAlPiUgDQogICNzZWUgb25seSBvYnNlcnZhdGlvbnMgd2hlcmUgdGhlIG1lYW4gYWRtaXNzaW9ucyBpbmNyZWFzZWQgZHVyaW5nIGNvdmlkIHllYXJzDQogIGZpbHRlcihkaWZmX21lYW5fcHJlY292aWRfcG9zdGNvdmlkIDw9IC0xKQ0KYGBgDQoNCmBgYHtyfQ0KaGJfc3BlY2lhbHR5ICU+JSANCiAgZmlsdGVyKHNwZWNpYWx0eSAhPSAiQWxsIiwNCiAgICAgICAgIGhiX25hbWUgIT0gIkFsbCBTY290bGFuZCIpICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgc3BlY2lhbHR5LCBpc193aW50ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX2FkbWlzc2lvbnNfY292aWQgPSBtZWFuKG51bWJlcl9hZG1pc3Npb25zKSwNCiAgICAgICAgICAgIG1lYW5fYWRtaXNzaW9uc19wcmVjb3ZpZCA9IG1lYW4oYXZlcmFnZTIwMTgyMDE5KSwNCiAgICAgICAgICAgICNnZXQgZGlmZiBpbiBtZWFucyBwcmVjb3ZpZCB2cyBkdXJpbmcgY292aWQNCiAgICAgICAgICAgIGRpZmZfbWVhbl9wcmVjb3ZpZF9wb3N0Y292aWQgPSBtZWFuX2FkbWlzc2lvbnNfcHJlY292aWQgLSBtZWFuX2FkbWlzc2lvbnNfY292aWQpICU+JSANCiAgI3NlZSBvbmx5IG9ic2VydmF0aW9ucyB3aGVyZSB0aGUgbWVhbiBhZG1pc3Npb25zIGluY3JlYXNlZCBkdXJpbmcgY292aWQgeWVhcnMNCiAgZmlsdGVyKGRpZmZfbWVhbl9wcmVjb3ZpZF9wb3N0Y292aWQgPD0gLTEpDQpgYGANCg0KDQoNCkZvciB0aGUgYXZlcmFnZSAyMDE4MjAxOSBhZG1pc3Npb25zLCBjZXJ0YWluIHNwZWNpYWx0aWVzIHNhdyBhbiBpbmNyZWFzZSBpbiBhdmVyYWdlIG51bWJlciBvZiBlbWVyZ2VuY3kgYWRtaXNzaW9ucyBwZXIgd2VlayBkdXJpbmcgdGhlIHdpbnRlciBwZXJpb2QuIFRoZXNlIHdlcmU6DQotTWVkaWNhbCAoYm90aCBpbmNsdWRpbmcgYW5kIGV4bHVkaW5nIENhcmRpb2xvZ3kgYW5kIENhbmNlcikNCi1QZWRpYXRyaWNzIChib3RoIGluY2x1ZGluZyBhbmQgZXhsdWRpbmcgQ2FyZGlvbG9neSBhbmQgQ2FuY2VyKQ0KDQpUaGVzZSBzYW1lIGluY3JlYXNlcyBhY3R1YWxseSBsZXNzZW5lZCBkdXJpbmcgdGhlIENvdmlkIHllYXJzIDIwMjAvMjAyMS8yMDIyIHRvIHRoZSBwb2ludCB3aGVyZSB0aGVyZSB3YXMgb25seSBhIHNtYWxsIGluY3JlYXNlIGR1cmluZyB0aGUgd2ludGVyIG1vbnRocy4gRHVyaW5nIHRoZSBDb3ZpZCB5ZWFycywgdGhlcmUgd2FzIGEgc2xpZ2h0IGluY3JlYXNlIGluIGF2ZXJhZ2UgbnVtYmVyIG9mIGVtZXJnZW5jeSBhZG1pc3Npb25zIHBlciB3ZWVrIGZvciBDYXJkaW9sb2d5IGFuZCBmb3IgU3VyZ2VyeSwgd2hpY2ggaXMgbm90YWJsZSBiZWNhdXNlIGF2ZXJhZ2UgZW1lcmdlbmN5IHN1cmdlcnkgYWRtaXNzaW9ucyBhY3R1YWxseSBkZWNyZWFzZWQgaW4gdGhlIHdpbnRlciBwcmUtQ292aWQNCg0KDQoNCg0KYGBge3J9DQojZ2V0IGxpbmUgZ3JhcGggb2YgYXZlcmFnZSBudW1iZXIgb2YgYWRtaXNzaW9ucyBvdmVyIHRpbWUgZm9yIGVhY2ggc3BlY2lhbHR5DQoNCmhiX3NwZWNpYWx0eSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IiwNCiAgICAgICAgIHNwZWNpYWx0eSAhPSAiQWxsIiwgDQogICAgICAgICBoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIHdlZWtfZW5kaW5nLCBzcGVjaWFsdHkpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fYWRtaXNzaW9ucyA9IG1lYW4obnVtYmVyX2FkbWlzc2lvbnMpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX2xpbmUoYWVzKHggPSB3ZWVrX2VuZGluZywNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuX2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BlY2lhbHR5KSkgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMyBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgKw0KICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIxLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgbGFicyh4ID0gIkRhdGUiLA0KICAgICAgIHkgPSAiQXZlcmFnZSBudW1iZXIgb2YgYWRtaXNzaW9ucyBwZXIgd2VlayIsDQogICAgICAgY29sb3VyID0gIlNwZWNpYWx0eSIpDQpgYGANCg0KYGBge3J9DQpoYl9zcGVjaWFsdHkgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIsDQogICAgICAgICBzcGVjaWFsdHkgIT0gIkFsbCIsIA0KICAgICAgICAgaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYl9uYW1lLCBtb250aCwgc3BlY2lhbHR5KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMgPSBtZWFuKGF2ZXJhZ2UyMDE4MjAxOSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gbW9udGgsDQogICAgICAgICAgICAgICAgICB5ID0gbWVhbl8yMDE4MjAxOV9hZG1pc3Npb25zLCANCiAgICAgICAgICAgICAgICAgIGNvbG91ciA9IHNwZWNpYWx0eSkpICsNCiAgICBnZW9tX2xpbmUoYWVzKHggPSBtb250aCwNCiAgICAgICAgICAgICAgICAgIHkgPSBtZWFuXzIwMTgyMDE5X2FkbWlzc2lvbnMsIA0KICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BlY2lhbHR5KSwgZ3JvdXAgPSBoYl9zcGVjaWFsdHkkc3BlY2lhbHR5KSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9NykpICsNCiAgbGFicyh4ID0gIkRhdGUiLA0KICAgICAgIHkgPSAiQXZlcmFnZSBudW1iZXIgb2YgYWRtaXNzaW9ucyBwZXIgd2VlayIsDQogICAgICAgY29sb3VyID0gIlNwZWNpYWx0eSIpDQpgYGANCg0KDQoNCg0KDQoNCiMjIEhTQ1AgQWdlL3NleCBkYXRhc2V0DQoNCiMjIyBWYXJpYWJsZXMgaW4gZGF0YXNldA0KDQpgYGB7cn0NCmhzY3BfYWdlc2V4IDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9jb3ZpZF9yYXdfZGF0YS9ob3NwaXRhbF9hZG1pc3Npb25zX2hzY3BfYWdlc2V4XzIwMjIwMzAyLmNzdiIpICU+JSBjbGVhbl9uYW1lcygpDQpgYGANCg0KYGBge3J9DQpoc2NwX2FnZXNleCAlPiUgbmFtZXMoKQ0KYGBgDQpBZ2FpbiwgdGhlIEhTQ1AgY29kZSBpcyBub3QgdmVyeSBoZWxwZnVsLCBpdCB3b3VsZCBiZSBtb3JlIHVzZWZ1bCB0byBoYXZlIHRoZSBIU0NQIG5hbWVzIGFuZCB0aGUgSEIgdGhleSBhcmUgdGllZCB0by4NCg0KYGBge3J9DQojcmVhZCBpbiBoc2NwIG5hbWVzIGRhdGFzZXQNCmhzY3BfbmFtZXMgPC0gcmVhZF9jc3YoInJhd19kYXRhL2NvdmlkX3Jhd19kYXRhL2hzY3BfbmFtZXMuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCg0KI3NlbGVjdCB0aGUgdmFyaWFibGVzIHdlIG5lZWQgdG8gYWRkIHRvIHRoZSBtYWluIHRhYmxlDQpoc2NwX25hbWVzIDwtIGhzY3BfbmFtZXMgJT4lIA0KICBzZWxlY3QoaHNjcCwgaHNjcF9uYW1lLCBoYiwgaGJfbmFtZSkNCmBgYA0KDQoNCg0KYGBge3J9DQojam9pbiB3aXRoIGhzY3BfbmFtZXMgdG8gZ2V0IGhzY3AgYW5kIGhiIG5hbWVzDQoNCmhzY3BfYWdlc2V4IDwtIGhzY3BfYWdlc2V4ICU+JSBsZWZ0X2pvaW4oaHNjcF9uYW1lcywgYnkgPSAiaHNjcCIpDQoNCmBgYA0KDQoNCiMjIyBDaGVjayB0byBzZWUgaWYgaGIgYW5kIGhzY3AgZGF0YXNldHMgYXJlIGludGVyY2hhbmdhYmxlDQoNCkkgbm90aWNlZCB0aGF0IEhTQ1AgYW5kIEhCIGRhdGFzZXRzIGNvbnRhaW5lZCB0aGUgc2FtZSB2YXJpYWJsZXMgYW5kIEhTQ1AgZGF0YXNldHMgY29udGFpbmVkIHRoZSBIQiBhcyB3ZWxsLCBzbyBJIHRob3VnaHQgdGhhdCB0aGV5IG1pZ2h0IGJlIGludGVyY2hhbmdhYmxlIHNpbmNlLCBpbiB0aGVvcnksIHdoZW4geW91IGdyb3VwIEhTQ1AgZGF0YXNldHMgYnkgSEIsIHRoZSBudW1iZXIgb2YgYWRtaXNzaW9ucyBzaG91bGQgYWdncmVnYXRlIHRvIHRoZSBzYW1lIG51bWJlcnMgYXMgdGhlIEhCIGRhdGFzZXRzIHNpbmNlIHRoZXkgYXJlIGZvciB0aGUgc2FtZSB0aW1lIHBlcmlvZHMuIFRoaXMgaXNuJ3QgdGhlIGNhc2UuIFRoZSBIU0NQIGRhdGFzZXQgcmVjb3JkZWQgaGlnaGVyIG51bWJlcnMgb2YgYWRtaXNzaW9ucyB3aGVuIGFnZ3JlZ2F0ZWQgYnkgSEIgYW5kIGNvbXBhcmVkIHdpdGggdGhlIEhCIGRhdGFzZXQuDQoNCmBgYHtyfQ0KI3N1bW1hcmlzZSBubyBvZiBhZG1pc3Npb25zIGJ5IHNleC9hZ2VfZ3JvdXAgZm9yIGVhY2ggSEINCmhzY3BfYWdlc2V4ICU+JSANCiAgZ3JvdXBfYnkoaGIsIHNleCwgYWdlX2dyb3VwLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYWRtaXNzaW9uc19ieV9zZXggPSBzdW0obnVtYmVyX2FkbWlzc2lvbnMpKQ0KYGBgDQoNCg0KYGBge3J9DQojc3VtbWFyaXNlIG5vIG9mIGFkbWlzc2lvbnMgYnkgc2V4L2FnZV9ncm91cCBmb3IgZWFjaCBIQg0KaGJfYWdlc2V4ICU+JSANCiAgZ3JvdXBfYnkoaGIsIHNleCwgYWdlX2dyb3VwLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYWRtaXNzaW9uc19ieV9zZXggPSBzdW0obnVtYmVyX2FkbWlzc2lvbnMpKQ0KYGBgDQoNCmBgYHtyfQ0KI2NoZWNrIG51bWJlciBvZiBhZG1pc3Npb25zIGluIGVhY2ggZGF0YXNldCBmb3IgYSByYW5kb20gSEIgZm9yIHRoZSBzYW1lIHdlZWtfZW5kaW5nIGRhdGUNCmhzY3BfYWdlc2V4ICU+JQ0KICBzZWxlY3Qod2Vla19lbmRpbmcsIGhiLCBhZ2VfZ3JvdXAsIHNleCwgYWRtaXNzaW9uX3R5cGUsIG51bWJlcl9hZG1pc3Npb25zKSAlPiUgDQogIGZpbHRlcihoYiA9PSAiUzA4MDAwMDE1IiwNCiAgICAgICAgIHdlZWtfZW5kaW5nID09ICIyMDIwMDEwNSIpICU+JSANCiAgZ3JvdXBfYnkod2Vla19lbmRpbmcsIGhiLCBzZXgsIGFnZV9ncm91cCwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2FkbWlzc2lvbnMgPSBzdW0obnVtYmVyX2FkbWlzc2lvbnMpKQ0KDQpoYl9hZ2VzZXggJT4lDQogIHNlbGVjdCh3ZWVrX2VuZGluZywgaGIsIGFnZV9ncm91cCwgc2V4LCBhZG1pc3Npb25fdHlwZSwgbnVtYmVyX2FkbWlzc2lvbnMpICU+JQ0KICBmaWx0ZXIoaGIgPT0gIlMwODAwMDAxNSIsDQogICAgICAgICB3ZWVrX2VuZGluZyA9PSAiMjAyMC0wMS0wNSIpICU+JSANCiAgZ3JvdXBfYnkod2Vla19lbmRpbmcsIGhiLCBzZXgsIGFnZV9ncm91cCwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2FkbWlzc2lvbnMgPSBzdW0obnVtYmVyX2FkbWlzc2lvbnMpKQ0KYGBgDQoNCldlIHNob3VsZCBhc2sgd2hpY2ggZGF0YXNldCBzaG91bGQgYmUgY29uc2lkZXJlZCAiY29ycmVjdCIgLSBJIHdvdWxkIHN1Z2dlc3Qgc2VsZWN0aW5nIHRoZSBIU0NQIGRhdGFzZXRzIGIvYyB0aGUgbnVtYmVycyBhcmUgaGlnaGVyLCB3aGljaCBtYWtlcyBtZSB0aGluayB0aGF0IHNvbWUgYWRtaXNzaW9ucyB3ZXJlbid0IHJlY29yZGVkIGluIHRoZSBIQiBkYXRhc2V0Lg0KDQoNCg0KQ2FuIHdlIGdldCB0aGUgcHJvcG9ydGlvbiBmb3Igbm8gb2YgYWRtaXNzaW9ucyB0byBwb3B1bGF0aW9uIGluIGVhY2ggSEIgb3IgSFNDUD8NClRoaXMgd291bGQgYWxsb3cgdXMgdG8gY2Fycnkgb3V0IHN0YXRpc3RpY2FsIHRlc3RzIHRvIHNlZSBpZiBhbnkgSEJzIG9yIEhTQ1BzIGhhdmUgYSBoaWdoZXIgcHJvcG9ydGlvbiBvZiBhZG1pc3Npb25zIGNvbXBhcmVkIHdpdGggU2NvdGxhbmQgb3ZlcmFsbA0KDQoNCg0KDQoNCiMjIEEmRSBhdHRlbmRhbmNlDQpgYGB7cn0NCmFlX3dhaXRfdGltZXMgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9tb250aGx5X2FlX3dhaXRpbmd0aW1lc18yMDIyMDYuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkNCmBgYA0KDQojIyMgVmFyaWFibGVzIGluIGRhdGFzZXQNCg0KYGBge3J9DQphZV93YWl0X3RpbWVzICU+JSBuYW1lcygpDQoNCmFlX3dhaXRfdGltZXMgJT4lIGRpc3RpbmN0KGhidCkgIyBub3RlOiBuZWVkIHRvIGpvaW4gaGIgbmFtZXMNCg0KYWVfd2FpdF90aW1lcyAlPiUgZmlsdGVyKGlzLm5hKG51bWJlcl9tZWV0aW5nX3RhcmdldF9hZ2dyZWdhdGUpKQ0KYGBgDQoNCmBgYHtyfQ0KI3NlbGVjdCBvbmx5IHZhcmlhYmxlcyBuZWVkZWQgZm9yIHN1bW1hcnkgdGFibGUNCmFlX2F0dGVuZGFuY2Vfc3VtbWFyeSA8LSBhZV93YWl0X3RpbWVzICU+JSANCiAgc2VsZWN0KG1vbnRoLCBoYnQsIG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUsIA0KICAgICAgICAgZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX2FkbWlzc2lvbl90b19zYW1lLA0KICAgICAgICAgZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX290aGVyX3NwZWNpYWx0eSwNCiAgICAgICAgIGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9yZXNpZGVuY2UsDQogICAgICAgICBkaXNjaGFyZ2VfZGVzdGluYXRpb25fdHJhbnNmZXIsDQogICAgICAgICBkaXNjaGFyZ2VfZGVzdGluYXRpb25fdW5rbm93bikNCmBgYA0KDQpgYGB7cn0NCiNjcmVhdGUgc2VwYXJhdGUgbW9udGggYW5kIHllYXIgY29sdW1ucw0KYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5IDwtIGFlX2F0dGVuZGFuY2Vfc3VtbWFyeSAlPiUgDQogIG11dGF0ZShtb250aF95ZWFyID0gbW9udGgsIC5iZWZvcmUgPSBtb250aCkNCg0KYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5IDwtIGFlX2F0dGVuZGFuY2Vfc3VtbWFyeSAlPiUgDQogIG11dGF0ZShtb250aCA9IG1vbnRoKHltKG1vbnRoX3llYXIpLCBsYWJlbCA9IFRSVUUpLA0KICAgICAgICAgeWVhciA9IHllYXIoeW0obW9udGhfeWVhcikpLCAuYWZ0ZXIgPSBtb250aF95ZWFyKQ0KYGBgDQoNCmBgYHtyfQ0KI2pvaW4gd2l0aCBoYl9uYW1lcw0KDQphZV9hdHRlbmRhbmNlX3N1bW1hcnkgPC0gYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5ICU+JSANCiAgbGVmdF9qb2luKGhiX25hbWVzLCBieSA9IGMoImhidCIgPSAiaGIiKSkNCmBgYA0KDQoNCmBgYHtyfQ0KI21ha2UgYWxsIHNjb3RsYW5kIGF0dGVuZGFuY2UgdGFibGUNCmFsbF9zY290bGFuZF9hdHRlbmRhbmNlIDwtIGFlX2F0dGVuZGFuY2Vfc3VtbWFyeSAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIGZpbHRlcih5ZWFyID49IDIwMTcpICU+JSANCiAgc3VtbWFyaXNlKG51bV9hdHRlbmRhbmNlcyA9IHN1bShudW1iZXJfb2ZfYXR0ZW5kYW5jZXNfYWdncmVnYXRlKSwNCiAgICAgICAgICAgIGFkbWlzc2lvbl90b19zYW1lID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9hZG1pc3Npb25fdG9fc2FtZSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIG90aGVyX3NwZWNpYWx0eSA9IHN1bShkaXNjaGFyZ2VfZGVzdGluYXRpb25fb3RoZXJfc3BlY2lhbHR5LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgcmVzaWRlbmNlID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9yZXNpZGVuY2UsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICB0cmFuc2ZlciA9IHN1bShkaXNjaGFyZ2VfZGVzdGluYXRpb25fdHJhbnNmZXIsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICB1bmtub3duID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl91bmtub3duLCBuYS5ybSA9IFRSVUUpKQ0KDQojZ2V0IHByb3BvcnRpb25zIGZvciBkZXN0aW5hdGlvbnMNCmFsbF9zY290bGFuZF9hdHRlbmRhbmNlIDwtIGFsbF9zY290bGFuZF9hdHRlbmRhbmNlICU+JSANCiAgcm93d2lzZSgpICU+JSANCiAgbXV0YXRlKA0KICAgIHRvdGFsX2F2Z19kaXNjaGFyZ2UgPSBzdW0oYyhhZG1pc3Npb25fdG9fc2FtZSwgb3RoZXJfc3BlY2lhbHR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpZGVuY2UsIHRyYW5zZmVyLCB1bmtub3duKSksDQogICAgcHJvcF9hZG1pc3Npb24gPSBhZG1pc3Npb25fdG9fc2FtZS90b3RhbF9hdmdfZGlzY2hhcmdlLA0KICAgIHByb3Bfb3RoZXJfc3BlY2lhbHR5ID0gb3RoZXJfc3BlY2lhbHR5L3RvdGFsX2F2Z19kaXNjaGFyZ2UsDQogICAgcHJvcF9yZXNpZGVuY2UgPSByZXNpZGVuY2UvdG90YWxfYXZnX2Rpc2NoYXJnZSwNCiAgICBwcm9wX3RyYW5zZmVyID0gdHJhbnNmZXIvdG90YWxfYXZnX2Rpc2NoYXJnZSwNCiAgICBwcm9wX3Vua25vd24gPSB1bmtub3duL3RvdGFsX2F2Z19kaXNjaGFyZ2UNCiAgKQ0KDQpgYGANCmBgYHtyfQ0KYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5IDwtIGFlX2F0dGVuZGFuY2Vfc3VtbWFyeSAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsIHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZShudW1fYXR0ZW5kYW5jZXMgPSBzdW0obnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSksDQogICAgICAgICAgIGFkbWlzc2lvbl90b19zYW1lID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9hZG1pc3Npb25fdG9fc2FtZSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIG90aGVyX3NwZWNpYWx0eSA9IHN1bShkaXNjaGFyZ2VfZGVzdGluYXRpb25fb3RoZXJfc3BlY2lhbHR5LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgcmVzaWRlbmNlID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9yZXNpZGVuY2UsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICB0cmFuc2ZlciA9IHN1bShkaXNjaGFyZ2VfZGVzdGluYXRpb25fdHJhbnNmZXIsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICB1bmtub3duID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl91bmtub3duLCBuYS5ybSA9IFRSVUUpKQ0KDQphZV9hdHRlbmRhbmNlX3N1bW1hcnkgPC0gYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5ICU+JSANCiAgcm93d2lzZSgpICU+JSANCiAgbXV0YXRlKA0KICAgIHRvdGFsX2F2Z19kaXNjaGFyZ2UgPSBzdW0oYyhhZG1pc3Npb25fdG9fc2FtZSwgb3RoZXJfc3BlY2lhbHR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpZGVuY2UsIHRyYW5zZmVyLCB1bmtub3duKSksDQogICAgcHJvcF9hZG1pc3Npb24gPSBhZG1pc3Npb25fdG9fc2FtZS90b3RhbF9hdmdfZGlzY2hhcmdlLA0KICAgIHByb3Bfb3RoZXJfc3BlY2lhbHR5ID0gb3RoZXJfc3BlY2lhbHR5L3RvdGFsX2F2Z19kaXNjaGFyZ2UsDQogICAgcHJvcF9yZXNpZGVuY2UgPSByZXNpZGVuY2UvdG90YWxfYXZnX2Rpc2NoYXJnZSwNCiAgICBwcm9wX3RyYW5zZmVyID0gdHJhbnNmZXIvdG90YWxfYXZnX2Rpc2NoYXJnZSwNCiAgICBwcm9wX3Vua25vd24gPSB1bmtub3duL3RvdGFsX2F2Z19kaXNjaGFyZ2UNCiAgKQ0KYGBgDQoNCg0KYGBge3J9DQojYWRkIGNvbHVtbnMgdG8gYWxsIHNjb3RsYW5kDQphbGxfc2NvdGxhbmRfYXR0ZW5kYW5jZSA8LSBhbGxfc2NvdGxhbmRfYXR0ZW5kYW5jZSAlPiUgDQogIG11dGF0ZShoYl9uYW1lID0gIkFsbCBTY290bGFuZCIpDQpgYGANCg0KYGBge3J9DQojc2VsZWN0IHJlbGV2YW50IGNvbHVtbnMNCmFlX2F0dGVuZGFuY2Vfc3VtbWFyeSA8LSBhZV9hdHRlbmRhbmNlX3N1bW1hcnkgJT4lIA0KICBmaWx0ZXIoeWVhciA+PTIwMTcpICU+JSANCiAgc2VsZWN0KHllYXIsIG1vbnRoLCBoYl9uYW1lLCBudW1fYXR0ZW5kYW5jZXMsIHByb3BfYWRtaXNzaW9uLCANCiAgICAgICAgIHByb3Bfb3RoZXJfc3BlY2lhbHR5LCBwcm9wX3Jlc2lkZW5jZSwgcHJvcF90cmFuc2ZlciwgcHJvcF91bmtub3duKQ0KDQphbGxfc2NvdGxhbmRfYXR0ZW5kYW5jZSA8LSBhbGxfc2NvdGxhbmRfYXR0ZW5kYW5jZSAlPiUgDQogIHNlbGVjdCh5ZWFyLCBtb250aCwgaGJfbmFtZSwgbnVtX2F0dGVuZGFuY2VzLCBwcm9wX2FkbWlzc2lvbiwNCiAgICAgICAgIHByb3Bfb3RoZXJfc3BlY2lhbHR5LCBwcm9wX3Jlc2lkZW5jZSwgcHJvcF90cmFuc2ZlciwgcHJvcF91bmtub3duKQ0KYGBgDQoNCmBgYHtyfQ0KI2JpbmQgcm93cw0KYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5IDwtIGFlX2F0dGVuZGFuY2Vfc3VtbWFyeSAlPiUgDQogIGJpbmRfcm93cyhhbGxfc2NvdGxhbmRfYXR0ZW5kYW5jZSkNCmBgYA0KDQpgYGB7cn0NCiNzZXBhcmF0ZSBkYXRhc2V0IGludG8gcHJlQ292aWQgYW5kIENvdmlkIHllYXIgcmFuZ2VzDQoNCmNvdmlkX2FlX2F0dGVuZGFuY2UgPC0gYWVfYXR0ZW5kYW5jZV9zdW1tYXJ5ICU+JSANCiAgZmlsdGVyKHllYXIgPj0gMjAyMCkNCg0KcHJlY292aWRfYWVfYXR0ZW5kYW5jZSA8LSBhZV9hdHRlbmRhbmNlX3N1bW1hcnkgJT4lIA0KICBmaWx0ZXIoeWVhciA8IDIwMjApDQpgYGANCg0KYGBge3J9DQojZ2V0IDIwMTctMjAxOSBhdmdzIHRvIGFkZCBhcyBjb21wYXJhdG9yIHRvIGNvdmlkIGRhdGFzZXQNCg0KcHJlY292aWRfYWVfYXR0ZW5kYW5jZSA8LSBwcmVjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19hdHRlbmRhbmNlc18yMDE3MTgxOSA9IG1lYW4obnVtX2F0dGVuZGFuY2VzKSwNCiAgICAgICAgICAgIGF2Z19wcm9wX2FkbWlzc2lvbl8yMDE3MTgyOSA9IG1lYW4ocHJvcF9hZG1pc3Npb24pLA0KICAgICAgICAgICAgYXZnX3Byb3Bfb3RoZXJfc3BlY2lhbHR5XzIwMTcxODE5ID0gbWVhbihwcm9wX290aGVyX3NwZWNpYWx0eSksDQogICAgICAgICAgICBhdmdfcHJvcF9yZXNpZGVuY2VfMjAxNzE4MTkgPSBtZWFuKHByb3BfcmVzaWRlbmNlKSwNCiAgICAgICAgICAgIGF2Z19wcm9wX3RyYW5zZmVyXzIwMTcxODE5ID0gbWVhbihwcm9wX3RyYW5zZmVyKSwNCiAgICAgICAgICAgIGF2Z19wcm9wX3Vua25vd25fMjAxNzE4MTkgPSBtZWFuKHByb3BfdW5rbm93bikpIA0KYGBgDQoNCmBgYHtyfQ0KDQojY3JlYXRlIGtleSB0byBqb2luIHdpdGggY292aWRfYWVfYXR0ZW5kYW5jZQ0KcHJlY292aWRfYWVfYXR0ZW5kYW5jZSA8LSBwcmVjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSANCiAgbXV0YXRlKGhiX2tleSA9IHBhc3RlMChoYl9uYW1lLCAiXyIsIG1vbnRoKSwgLmJlZm9yZSA9IGhiX25hbWUpDQoNCiNzZWxlY3Qgb25seSBrZXkgYW5kIGF2ZyB2YXJpYWJsZXMNCnByZWNvdmlkX2FlX2F0dGVuZGFuY2UgPC0gcHJlY292aWRfYWVfYXR0ZW5kYW5jZSAlPiUgDQogIHN1YnNldChzZWxlY3QgPSAtYyhoYl9uYW1lLCBtb250aCkpDQoNCiAgDQpgYGANCg0KYGBge3J9DQpjb3ZpZF9hZV9hdHRlbmRhbmNlIDwtIGNvdmlkX2FlX2F0dGVuZGFuY2UgJT4lIA0KICBtdXRhdGUoaGJfa2V5ID0gcGFzdGUwKGhiX25hbWUsICJfIiwgbW9udGgpLCAuYmVmb3JlID0gaGJfbmFtZSkNCmBgYA0KDQpgYGB7cn0NCmNvdmlkX2FlX2F0dGVuZGFuY2UgPC0gY292aWRfYWVfYXR0ZW5kYW5jZSAlPiUgDQogIGxlZnRfam9pbihwcmVjb3ZpZF9hZV9hdHRlbmRhbmNlLCBieSA9ICJoYl9rZXkiKQ0KDQoNCmBgYA0KDQoNCg0KYGBge3J9DQpjb3ZpZF9hZV9hdHRlbmRhbmNlIDwtIGNvdmlkX2FlX2F0dGVuZGFuY2UgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IChwYXN0ZTAoeWVhciwgIi0iLCBtb250aCkpLCAuYmVmb3JlID0geWVhcikgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHltKGRhdGUpLCAuYmVmb3JlID0geWVhcikNCg0KYGBgDQoNCmBgYHtyfQ0KI3B1dCBkYXRhIGluIGxvbmcgZm9ybWF0DQoNCmNvdmlkX2FlX2F0dGVuZGFuY2UgPC0gY292aWRfYWVfYXR0ZW5kYW5jZSAlPiUgDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoInByb3AiKSwNCiAgICBuYW1lc190byA9ICJkZXN0aW5hdGlvbiIsDQogICAgdmFsdWVzX3RvID0gImRlc3RpbmF0aW9uX3Byb3AiDQogICkNCg0KY292aWRfYWVfYXR0ZW5kYW5jZSA8LSBjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSANCiAgbXV0YXRlKA0KICAgIGF2Z19wcm9wXzIwMTcxODE5ID0gY2FzZV93aGVuKA0KICAgICAgZGVzdGluYXRpb24gPT0gInByb3BfYWRtaXNzaW9uIiB+IGF2Z19wcm9wX2FkbWlzc2lvbl8yMDE3MTgyOSwNCiAgICAgIGRlc3RpbmF0aW9uID09ICJwcm9wX290aGVyX3NwZWNpYWx0eSIgfiBhdmdfcHJvcF9vdGhlcl9zcGVjaWFsdHlfMjAxNzE4MTksDQogICAgICBkZXN0aW5hdGlvbiA9PSAicHJvcF9yZXNpZGVuY2UiIH4gYXZnX3Byb3BfcmVzaWRlbmNlXzIwMTcxODE5LA0KICAgICAgZGVzdGluYXRpb24gPT0gInByb3BfdHJhbnNmZXIiIH4gYXZnX3Byb3BfdHJhbnNmZXJfMjAxNzE4MTksDQogICAgICBkZXN0aW5hdGlvbiA9PSAicHJvcF91bmtub3duIiB+IGF2Z19wcm9wX3Vua25vd25fMjAxNzE4MTkNCiAgICApDQogICkNCg0KY292aWRfYWVfYXR0ZW5kYW5jZSA8LSBjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSANCiAgc2VsZWN0KGRhdGUsIHllYXIsIG1vbnRoLCBoYl9rZXksIGhiX25hbWUsIG51bV9hdHRlbmRhbmNlcywgDQogICAgICAgICBhdmdfYXR0ZW5kYW5jZXNfMjAxNzE4MTksIGRlc3RpbmF0aW9uLA0KICAgICAgICAgZGVzdGluYXRpb25fcHJvcCwgYXZnX3Byb3BfMjAxNzE4MTkpDQoNCg0KYGBgDQoNCg0KIyMjIEdyYXBocyBmb3IgZGFzaGJvYXJkDQpgYGB7cn0NCmNvdmlkX2FlX2F0dGVuZGFuY2VfcGxvdGx5IDwtIGNvdmlkX2FlX2F0dGVuZGFuY2UgJT4lIA0KICBmaWx0ZXIoaGJfbmFtZSA9PSAiQWxsIFNjb3RsYW5kIikgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBkYXRlLA0KICAgICAgICAgICAgICAgICB5ID0gbnVtX2F0dGVuZGFuY2VzLA0KICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJEYXRlOiAiLCB5ZWFyLCAiLSIsIG1vbnRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgYWRtaXNzaW9uczogIiwgbnVtX2F0dGVuZGFuY2VzLA0KICAgICAgICAgICAgICAgICAiPGJyPiIsDQogICAgICAgICAgICAgICAgICIyMDE3LTIwMTkgYXZnIGFkbWlzc2lvbnM6ICIsIA0KICAgICAgICAgICAgICAgICByb3VuZChhdmdfYXR0ZW5kYW5jZXNfMjAxNzE4MTkpKSkpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gZGF0ZSwNCiAgICAgICAgICAgICAgICB5ID0gbnVtX2F0dGVuZGFuY2VzKSkgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMyBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgKw0KICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMS0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiKSsNCiAgbGFicyh0aXRsZSA9ICJOdW1iZXIgb2YgYXR0ZW5kYW5jZXMgYXQgQSZFIDIwMjAgLSAyMDIyIFxuIiwNCiAgICAgICB4ID0gIkRhdGUiLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEF0dGVuZGFuY2VzIikNCmNvdmlkX2FlX2F0dGVuZGFuY2VfcGxvdGx5ICU+JSANCiAgZ2dwbG90bHkodG9vbHRpcCA9ICJ0ZXh0IikgJT4lIA0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkgJT4lIA0KICBsYXlvdXQoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIpKQ0KYGBgDQoNCmBgYHtyfQ0KY292aWRfYWVfZGVzdGluYXRpb25zX3Bsb3RseSA8LSBjb3ZpZF9hZV9hdHRlbmRhbmNlICU+JSANCiAgZmlsdGVyKGhiX25hbWUgPT0gIkFsbCBTY290bGFuZCIpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gZGF0ZSwNCiAgICAgICAgICAgICAgICAgeSA9IGRlc3RpbmF0aW9uX3Byb3AsDQogICAgICAgICAgICAgICAgIGNvbG91ciA9IGRlc3RpbmF0aW9uLA0KICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJEYXRlOiAiLCB5ZWFyLCAiLSIsIG1vbnRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVyY2VudGFnZTogIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChkZXN0aW5hdGlvbl9wcm9wKjEwMCwgZGlnaXRzID0gMiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTctMjAxOSBwZXJjZW50YWdlOiAiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGF2Z19wcm9wXzIwMTcxODE5KjEwMCwgZGlnaXRzID0gMiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiUiKSkpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gZGF0ZSwNCiAgICAgICAgICAgICAgICAgeSA9IGRlc3RpbmF0aW9uX3Byb3AsDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBkZXN0aW5hdGlvbikpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjMgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAiJWIgJVkiKSArDQogIHNjYWxlX3lfc3FydCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkgKw0KICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIikrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMS0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiKSsNCiAgbGFicyh0aXRsZSA9ICJEZXN0aW5hdGlvbiBvZiBhdHRlbmRhbmNlcyBhdCBBJkUgMjAyMCAtIDIwMjIgXG4iLA0KICAgICAgIHggPSAiRGF0ZSIsDQogICAgICAgeSA9ICJQcm9wb3J0aW9uIG9mIGF0dGVuZGFuY2VzIiwNCiAgICAgICBjb2xvdXIgPSAiRGVzdGluYXRpb24iKQ0KY292aWRfYWVfZGVzdGluYXRpb25zX3Bsb3RseSAlPiUgDQogIGdncGxvdGx5KHRvb2x0aXAgPSAidGV4dCIpICU+JSANCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQoNCg0KYGBgDQoNCiMjIFdhaXRpbmcgdGltZXMgLSBMbG95ZCdzIGdyYXBoDQoNCiMjIyBSZWFkIGRhdGEsIG1hbmlwdWxhdGUgdGFibGUNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkobHVicmlkYXRlKQ0KDQp3YWl0aW5nX3RpbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvbW9udGhseV9hZV93YWl0aW5ndGltZXNfMjAyMjA2LmNzdiIpICU+JSBjbGVhbl9uYW1lcygpDQoNCmBgYA0KDQpgYGB7cn0NCiNnZXQgZGF0ZSBhbmQgcXVhcnRlciB2YWx1ZXMgDQp3YWl0aW5nX3RpbWVzIDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHltKG1vbnRoKSwNCiAgICAgICAgIHF1YXJ0ZXIgPSBxdWFydGVyKGRhdGUpKQ0KYGBgDQoNCmBgYHtyfQ0KI2dldCBwcm9wb3J0aW9ucyBmb3IgYWxsIGRlc3RpbmF0aW9ucw0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzICU+JSANCiAgbXV0YXRlKA0KICAgIHByb3BfYWRtaXNzaW9uX3RvX3NhbWUgPSAoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX2FkbWlzc2lvbl90b19zYW1lL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpDQogICkgJT4lIA0KICBtdXRhdGUocHJvcF9vdGhlcl9zcGVjaWFsaXR5ID0gKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9vdGhlcl9zcGVjaWFsdHkvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkpICU+JSANCiAgbXV0YXRlKHByb3BfcmVzaWRlbmNlID0gKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9yZXNpZGVuY2UvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkpICU+JSANCiAgbXV0YXRlKHByb3BfdHJhbnNmZXIgPSAoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX3RyYW5zZmVyL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpKSAlPiUgDQogIG11dGF0ZShwcm9wX3Vua25vd24gPSAoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uX3Vua25vd24vbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkpIA0KYGBgDQoNCmBgYHtyfQ0KI2NoYW5nZSB0byBsb25nIGZvcm1hdA0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IHByb3BfYWRtaXNzaW9uX3RvX3NhbWU6cHJvcF91bmtub3duLCBuYW1lc190byA9ICJkaXNjaGFyZ2VfZGVzdGluYXRpb24iLCB2YWx1ZXNfdG8gPSAiZGlzY2hhcmdlX3Byb3BvcnRpb24iKQ0KDQojY2xlYW4gdXAgdmFsdWVzIGZvciBkZXN0aW5hdGlvbnMNCndhaXRpbmdfdGltZXMgPC0gd2FpdGluZ190aW1lcyAlPiUNCiAgbXV0YXRlKGRpc2NoYXJnZV9kZXN0aW5hdGlvbiA9IGNhc2Vfd2hlbigNCiAgICBzdHJfZGV0ZWN0KGRpc2NoYXJnZV9kZXN0aW5hdGlvbiwgInByb3BfYWRtaXNzaW9uX3RvX3NhbWUiKSB+IA0KICAgICAgIkFkbWlzc2lvbiB0byBTYW1lIEZhY2lsaXR5IiwNCiAgICBzdHJfZGV0ZWN0KGRpc2NoYXJnZV9kZXN0aW5hdGlvbiwgInByb3Bfb3RoZXJfc3BlY2lhbGl0eSIpIH4gDQogICAgICAiRGlzY2hhcmdlZCB0byBwcml2YXRlIHByb3ZpZGVyL2RpZWQiLA0KICAgIHN0cl9kZXRlY3QoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uLCAicHJvcF9yZXNpZGVuY2UiKSB+IA0KICAgICAgIkRpc2NoYXJnZWQgdG8gcHJpdmF0ZSByZXNpZGVuY2UiLA0KICAgIHN0cl9kZXRlY3QoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uLCAicHJvcF90cmFuc2ZlciIpIH4gDQogICAgICAiVHJhbnNmZXJyZWQgdG8gYW5vdGhlciBOSFMgcHJvdmlkZXIiLA0KICAgIHN0cl9kZXRlY3QoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uLCAicHJvcF91bmtub3duIikgfiANCiAgICAgICJVbmtub3duIG9yIG90aGVyIGRpc2NoYXJnZSBkZXN0aW5hdGlvbiINCiAgKSkNCmBgYA0KDQoNCiMjIyBHcmFwaHMgZm9yIGRhc2hib2FyZA0KDQpgYGB7cn0NCiNyZWFkIGluIGNsZWFuIGRhdGENCndhaXRpbmdfdGltZXMgPC0gcmVhZF9jc3YoImNsZWFuX2RhdGEvd2FpdF90aW1lcy5jc3YiKQ0KYGBgDQoNCg0KYGBge3J9DQp3aW50ZXJfcGxvdGx5IDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoZGlzY2hhcmdlX2Rlc3RpbmF0aW9uID09ICJBZG1pc3Npb24gdG8gU2FtZSBGYWNpbGl0eSIsDQogICAgICAgICAhaXMubmEoZGlzY2hhcmdlX3Byb3BvcnRpb24pKSAlPiUgDQogIGdyb3VwX2J5KGRhdGUpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fYWRtaXNzaW9uX3RvX3NhbWUgPSBtZWFuKGRpc2NoYXJnZV9wcm9wb3J0aW9uKSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBkYXRlLA0KICAgICAgICAgeSA9IG1lYW5fYWRtaXNzaW9uX3RvX3NhbWUsDQogICAgICAgICB0ZXh0ID0gIHBhc3RlMCgiRGF0ZTogIiwgZGF0ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmNlbnRhZ2U6ICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQobWVhbl9hZG1pc3Npb25fdG9fc2FtZSoxMDAsIGRpZ2l0cyA9IDIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlIikpKSArDQogIGdlb21fbGluZShhZXMoeCA9IGRhdGUsDQogICAgICAgICB5ID0gbWVhbl9hZG1pc3Npb25fdG9fc2FtZSkpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjYgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAgIiViICVZIikgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9NykpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMDktMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMC0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTItMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMy0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTUtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTgtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOS0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00LCBjb2xvdXIgPSAiZ3JleTUwIiwgYWxwaGEgPSAwLjcpKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjEtMDEtMDEiKSksIGxpbmV0eXBlPTQsIGNvbG91ciA9ICJncmV5NTAiLCBhbHBoYSA9IDAuNykrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMi0wMS0wMSIpKSwgbGluZXR5cGU9NCwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0gMC43KSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiBhdHRlbmRhbmNlcyB0byBzZWxlY3RlZCBkZXN0aW5hdGlvbiBcbiIsDQogICAgICAgeCA9ICJcbiBEYXRlIiwNCiAgICAgICB5ID0gIlByb3BvcnRpb24gb2YgYXR0ZW5kYW5jZXMiKQ0KDQp3aW50ZXJfcGxvdGx5ICU+JSANCiAgZ2dwbG90bHkodG9vbHRpcCA9ICJ0ZXh0IikgJT4lIA0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkgJT4lIA0KbGF5b3V0KGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiKSkNCg0KYGBgDQoNCg==